2011-03-11 128 views
2

希望我不會因爲這個太糟糕而惹火 - 我已經盡力找到一個無效的答案。在Ruby on Rails中聲明關聯

我想知道如果有人能幫我弄清楚如何在Ruby on Rails中正確聲明關聯(3)。目前,我有3種型號:

#room.rb 
class Room < ActiveRecord::Base 
    has_many :check_ins 
end 

#check_in.rb 
class CheckIn < ActiveRecord::Base 
    belongs_to :user 
    belongs_to :room 
end 

#user.rb 
class User < ActiveRecord::Base 
    has_one :check_in 
end 

到目前爲止,我沒有做過任何遷移到foreign_key列添加到我的任何表(不Rails的爲你做這個?)。

我很困惑爲什麼命令CheckIn.first.user返回nil而命令User.first.check_in返回SQLite3::SQLException: no such column。分別與CheckIn.first.roomRoom.first.check_ins相同。爲了使User.first.check_in返回與第一個用戶關聯的CheckIn對象和Room.first.check_ins返回與第一個Room關聯的CheckIns集合,我需要做什麼?

任何幫助將非常感激。

查理

回答

4

你最初是怎麼生成這些模型的?你只是做了模型文件,還是使用了rails的模型生成器(它也爲你生成了一個遷移)?

#room.rb 
class Room < ActiveRecord::Base 
    has_many :check_ins 
end 

#check_in.rb 
class CheckIn < ActiveRecord::Base 
    belongs_to :user 
    belongs_to :room 
end 

#user.rb 
class User < ActiveRecord::Base 
    has_one :check_in 
    has_one :room, :through => :check_in 
end 

以dB /遷移/ 34612525162_something_something.rb你需要確保你有一個設置這些表爲您的遷移。爲你做這將是在一個控制檯運行此命令,修改爲使用您想要的字段的命令最簡單的方法,需要的* _id字段進行關聯的工作:

rails generate model user name:string email:string otherfield:integer 
rails generate model check_in user_id:integer room_id:integer 
rails generate model room number:integer 

注意這些也會爲你生成模型文件,因爲你已經有了這3個模型文件,它會問你是否要覆蓋它們,或跳過這些文件。你可以跳過它,它應該很好。 如果你已經有了在這些模型中的數據的一部分,那麼您可以通過運行該發電機代替只是添加USER_ID和ROOM_ID領域的CHECK_IN模型的遷移:

rails generate migration AddIdsToCheckIn user_id:integer room_id:integer 

爲Rails 2.3.x版本替換rails generatescript/generate。接下來,您可以通過打開db/migrate.rb中的文件來檢查您的遷移,並在需要時修改它們。最後,運行遷移:

rake db:migrate 

它應該爲你工作。請注意,我向用戶添加了一個has_one, :through =>的關係 - 這樣您就可以做@user.room而不必製作3個連鎖:@user.check_in.room

+0

很好的答案 - 非常具有描述性!我錯過的主要想法是我需要通過遷移將user_id和room_id列添加到check_in。另外,感謝關​​於':through'的提示 - 這會派上用場! – candrews 2011-03-11 18:49:14

0

您需要添加遷移自己(或者,如果你不活,你可以修改現有的遷移)。基本上,你需要給這個關係的belongs_to一個外鍵。

+0

這個結果非常好!我最終用來生成這種遷移的命令(對於任何可能在將來會發現這種情況的人)是'rails g migration add_room_id_to_check_ins room_id:integer'(顯然後面跟着'rake db:migrate')。謝謝您的幫助! – candrews 2011-03-11 18:36:19

+0

@candrews顯然我輸入得太慢了:p – nzifnab 2011-03-11 18:44:11

+0

哈哈,好吧,他們都是很好的答案,只是速度更快。我有點感到厭倦= p – candrews 2011-03-11 22:03:19

0

絕對沒有理由得到火焰不要擔心:)看起來你在這裏試圖做一個到多個協會,但你實際上在做一個多對多的協會。

如果用戶有一張入住卡,這意味着他/她有一個房間。所以,你可以只是:

用戶HAS_ONE房 房屬於用戶

和房間有一個USER_ID。

希望能幫到:)

+0

哈哈,非常感謝你的信心boost = p我的問題應該更窄一些 - 還有其他一些CheckIn屬性,使CheckIn有意義它自己的模型。凱文的回答指出我的方向正確,但我已經明白了。謝謝! – candrews 2011-03-11 18:34:54

+0

不客氣,我很高興你已經把它全部設置:) – Spyros 2011-03-11 20:28:42