2012-06-08 26 views
0

我有兩個型號:UserLocation如下:如何在模型和表單構建器中使用外鍵?

class User < ActiveRecord::Base 
    attr_accessible :location, :password, :user_name, :password_confirmation 

    validates :location, :user_name, :presence => true 
    validates :password, :presence => true, :confirmation => true 

    has_one :location, :foreign_key => 'location' 

end 

class Location < ActiveRecord::Base 
    attr_accessible :loc_id, :loc_name 

    belongs_to :user, :foreign_key => 'loc_id' 
end 

你可以看到,我使用自定義foreign_key的車型。我使用表單生成器來構建一個用戶註冊的形式,但是當我提交的數據出現錯誤:

Location(#2170327880) expected, got String 

我用simple_form構建表單,相關的代碼是:

= f.input :location, :collection => Location.all.collect {|c| [c.loc_name, c.loc_id]} 

我怎麼能解決這個問題?或者我必須使用默認foreign_key,如location_id用於關聯?

謝謝。

更新:

當我在User模型重命名location領域loc_id並刪除:foreign_key這樣的:

class User < ActiveRecord::Base 
    attr_accessible :loc_id, :password, :user_name, :password_confirmation 

    validates :loc_id, :user_name, :presence => true 
    validates :password, :presence => true, :confirmation => true 

    has_one :location, :foreign_key => 'location' 

end 

class Location < ActiveRecord::Base 
    attr_accessible :loc_id, :loc_name 

    belongs_to :user 
end 

它工作正常。但我仍然想知道如何關聯UserLocation模型。

P.S.我使用Location模型來存儲國家代碼和國家名稱,這將永遠不會被User更新。

+0

多個用戶可以擁有相同的位置? –

+0

是的。 'location'表是一個靜態數據表。我將把所有的城市都保存在桌子上,並給它一個唯一的ID。在用戶表中,我將保存城市ID而不是城市名稱。 – zhu0qun

回答

1

這聽起來像你真正想擁有

class User < ActiveRecord::Base 
    belongs_to :location 
end 

class Location < ActiveRecord::Base 
    has_many :users 
end 

這意味着用戶具有location_id列。如果您以相反的方式執行操作(位置上的user_id列),那麼給定的位置只能關聯到一個用戶。軌道方式是位置表中id列的用戶點上的location_id。如果您希望它指向不同的列,請使用:primary_key選項(如果要將用戶列設置爲location_id以外的其他列,請使用:foreign_key選項)

就表單而言,您無法做f.select :location - 表單不知道如何傳輸這樣的複雜對象。在這種情況下,你要設置的形式來控制LOCATION_ID屬性,即

= f.input :location_id, :collection => Location.all.collect {|c| [c.loc_name, c.id]} 

如果你走具有位置ID列是指在位置loc_id列的路線,那麼你需要改變這是

= f.input :location_id, :collection => Location.all.collect {|c| [c.loc_name, c.loc_id]} 

個人,如果你只是剛剛開始接觸軌我會堅持到默認

+0

謝謝!今天我閱讀了Rails指南,並理解這一點。 – zhu0qun

1

它看起來像你在濫用外鍵。在用戶模型中,您應該只有has_one :location,位置模型應具有user_id屬性。在位置模型中,您只需編寫belongs_to :user。外鍵始終是另一個(外部)表的索引。

+0

感謝您的回答。我是Rails的新手,你能解釋我怎樣才能在'location'和'loc_id'字段之間建立關聯? – zhu0qun

0
class User < ActiveRecord::Base 
    # stuff 

    has_one :location  
end 

class Location < ActiveRecord::Base 
    # more stuff 

    belongs_to :user 
end 
+0

嗨,我將'user_id'字段添加到位置表中,但錯誤仍然存​​在:( – zhu0qun

+0

您究竟如何添加user_id列?通過遷移?您能否在此處發佈您的schema.rb文件? –

+0

是的,我使用遷移將列添加到位置表中我剛剛更新了我的問題,當我將列位置重命名爲loc_id時,我發現錯誤消失,但我不知道如何直接在這些模型之間建立關聯 – zhu0qun

0

如果您最終想要做的是選擇具有相同位置的所有用戶,則可能需要將模型設置稍微不同。現在,由於每個用戶在位置表中都有自己的位置記錄,因此最終會出現重複的位置,您必須找到所有這些位置以獲取唯一位置並從中提取user_ids。

而是做到這一點

class User < ActiveRecord::Base 
    has_one :placement 
    has_one :location, through: :placement 
end 

class Placement < ActiveRecord::Base 
    belongs_to :user 
    belongs_to :location 
end 

class Location < ActiveRecord::Base 
    has_many :placements 
    has_many :users, through: :placements 
end 

。至於遷移,Placement應該有一個:user_id和:location_id。您可以刪除當前位置中的:user_id。這段代碼說的是,我們有很多用戶,我們有很多獨特的位置,我們通過創建展示位置來將用戶置於唯一位置,這表明具有以下內容的用戶:user_id位於以下位置:location_id。此外,請不要忘記添加一行

add_index :placements, [:user_id, :location_id], unique: true 

這樣您就不能將用戶放置在不止一次的位置。

編輯:忘了補充:只需獲取位置記錄和調用位置,即可獲取位置中的所有用戶。用戶

相關問題