2016-06-21 100 views
2

我有以下型號:軌道4 find_or_create_by與accepts_nested_attributes

class Foo < ActiveRecord::Base 
    belongs_to :bar 
    accepts_nested_attributes_for :bar 
end 

class Bar < ActiveRecord::Base 
    has_many :foo 
end 

欄包括 '對象' 和Foo包含 '標籤'。

我可以做到以下幾點:

f=Foo.create(:label=>"label",:bar_attributes=>{:object=>"mason jar"}) 

這工作得很好。

不過,我WANT做的是:

f=Foo.find_or_create_by(:label=>"label",:bar_attributes=>{:object=>"mason jar"}) 

的問題是,這種失敗與SQL錯誤

ActiveRecord::StatementInvalid: SQLite3::SQLException: no such column: bar_attributes.object: SELECT "foo".* FROM "foo" WHERE "foo"."label" = ? AND "bar_attributes"."object" = 'mason jar' LIMIT 1 

我可以理解爲什麼發生這種情況,但我想能夠使用該功能。我知道我需要添加代碼來爲Bar執行「find_or_create_by」,但我已經在使用這個工具了,所以我不會將它放在這裏,只是我目前遇到的問題。

那麼,有沒有辦法讓Foo的'find'只是IGNORE bar_attributes,並且只有在需要時才使用它(用於創建)?

或者,還有另一種方法來實現這一目標嗎?

編輯:解釋這是爲什麼事情是這樣的:我們有兩個不同的對象

。酒吧是一個獨立的對象。 Foo是一個單獨的包含Bar的對象類型。

所以,我們可以有幾個記錄吧:

Mason jar 
Shovel 
Can of corn 

而且我們可以有其他記錄在富:​​

label: 123 => Bar: Shovel 
label: 456 => Bar: Shovel 
label: 123 => Bar: Can of corn 

所有酒吧的Foo中是有效的酒吧的,但只有酒吧與標籤在Foo裏是Foo。

所以,基本上,我希望能夠運行:

f = Foo.find_or_create_by(:label=>'label',:bar_attributes=>{:object='object'}) 

,並有必要時它創建了吧,然後在必要時創建富。

我希望這會有所幫助。

+0

您可以鏈接find_or_create_by:where或任何自定義作用域。您是否在使用'find_or_create_by'之前嘗試過使用where子句? –

+0

那麼,一般來說,嵌套屬性曾經是一個寶石,後來被合併到Rails中,所以無論適用於ActiveRecord,都不必使用嵌套屬性。你是否試圖創建一個Foo對象,以防帶有某些屬性的Bar對象不存在? – 2016-06-21 18:36:00

+0

不是所有的代碼都在上面。簡而言之,我想要做的是在Bar上運行find_or_create_by,然後在Foo上使用find_or_create_by的結果。 –

回答

1

我想,你可以做這樣的:

f = Foo.find_or_create_by(label: 'label', bar: Bar.find_or_create_by(object: 'object')) 

它相當於

F = Foo.find_or_create_by(標籤: '標籤',bar_id:Bar.find_or_create_by(對象:對象')。id)

您可能想要兩行來檢查Bar是否已創建(沒有驗證失敗)。