2010-10-01 72 views
61

喜(巨大的Rails新手在這裏),我有以下型號:的Rails:創建HAS_ONE協會

class Shop < ActiveRecord::Base 
    belongs_to :user 
    validates_uniqueness_of :title, :user_id, :message => "is already being used" 
end 

class User < ActiveRecord::Base 
    has_one :shop, :dependent => :destroy 
end 

當我要創建一個新的店,我出現以下錯誤:

private method `create' called for nil:NilClass 

這是我的控制器:

@user = current_user 
@shop = @user.shop.create(params[:shop]) 

我試過不同的變化,通過閱讀指南和教程在這裏和那裏,但我比以前更困惑,無法讓它工作。任何幫助將不勝感激。

+0

編輯問題的標題來反映問題。複製[在rails中使用has_one關聯構建](http://stackoverflow.com/questions/2472982/using-build-with-a-has-one-association-in-rails) – 2012-05-09 18:53:44

+1

您也可以使用'@ user.build_shop(params)' – ImranNaqvi 2016-06-04 05:58:11

回答

82

首先,這裏是如何做你想要的:

@user = current_user 
@shop = Shop.create(params[:shop]) 
@user.shop = @shop 

現在,這裏就是爲什麼你的版本沒有工作:

你可能認爲,如果用戶有一個has_many這可能是因爲工作與店鋪的關係,@user.shops.create(params[:shop])工作。然而,有has_many關係和has_one之間的關係有很大的區別:

隨着has_many關係,shops返回一個ActiveRecord集合對象,其中有您可以使用商店從用戶中添加或刪除/方法。其中一種方法是create,它創建一個新的商店並將其添加到用戶。

通過has_one關係,您不會收回這樣一個收集對象,而只是屬於該用戶的Shop對象 - 或者如果用戶還沒有商店,則返回nil。由於Shop對象和零都沒有create方法,所以不能使用create這種方式與has_one關係。

+0

感謝您的回答,sepp2k。我現在看到爲什麼我的代碼無法工作。 – Neko 2010-10-01 14:21:24

+78

您也可以使用'@ user.create_shop(params [:shop])''。查看[通過has_one添加的方法](http://guides.rubyonrails.org/association_basics.html#methods-added-by-has_one)。 – nates 2013-04-08 21:01:16

+0

選擇的答案有效,但@nates解決方案也適用。 +1給你們兩個。 – nfriend21 2013-07-02 01:38:05

147

更簡潔的方式來做到這一點是:

@user.create_shop(params[:shop]) 

看到紅寶石methods added by has_one on Rails的指南。

+3

這絕對是更好的方法 – Magnum 2016-03-23 14:20:49

+2

請注意,如果您create_shop不止一次,它會刪除以前的商店。例如,如果運行'@ user.create_shop(params [:shop_one_info])'它會創建shop_one,但是如果運行'@ user.create_shop(params [:shop_two_info])'它會刪除第一個商店並創建第二個。 – ecoding5 2016-05-06 17:08:41

+0

關於刪除以前的商店的上述評論是針對Rails 3.2.18的,不知道更近的版本。 5分鐘後無法編輯評論-_- – ecoding5 2016-05-06 17:15:22

2

兩個更多,如果你想save而不是create方式:

shop = @user.build_shop 
shop.save 

shop = Show.new 
shop.user = @user 
shop.save