2012-10-20 203 views
3

我想像這樣的查詢。使用find_or_create_by創建一個包含嵌套對象的對象

Movie.find_or_create_by_title(title: 'foo').photos.find_or_create_by_name(name: 'bar') 

給定的查詢將創建Photo對象,但不會考慮其父Movie

=> #<Photo id: 3, movie_id: nil … 

有什麼辦法可以將電影傳給它嗎?

更新:我試圖「同時保存」的原因是因爲我有一個需要電影至少有一張照片的驗證。請參閱:https://stackoverflow.com/a/12962317/471313

回答

4

我使用的是最新的Rails 3.2的語法find_or_create_by,因爲它會在Rails的4.0被棄用。最重要的是有accepts_nested_attributes_for電影模型像這樣:

class Movie < ActiveRecord::Base 
    has_many :photos 
    accepts_nested_attributes_for :photos 
end 

這使您可以指定與形式<relation-name>_attributes模型中的關鍵屬性,你的情況photo_attributes

@movie = Movie.where(:title => 'foo').first_or_create :director => 'Steven Speilberg', 
                 :photos_attributes => [{ 
                 :caption => "Thrilling!" 
                 }] 
@movie.save 

在此之後,您只需保存父模型,而且會自動在你的情況再次的照片保存在兒童模特。有必要先保存父母,因爲孩子需要知道要放入子記錄的ID。因此在保存@movie之後,它會將其ID置於照片記錄的movie_id字段中。它不能在父母之前保存孩子,因爲那樣它就不知道要使用什麼ID。

如果你使用一個Rails 3.2版之前,它會是這個樣子:

@movie = Movie.find_or_create_by_title "W00t!", :director => 'Steven Speilberg', 
               :photos_attributes => [{ 
                :caption => "Thrilling!" 
               }] 
+0

我得到一個'ActiveRecord :: UnknownAttributeError:未知屬性:photo_attributes'與您的解決方案。 – Martin

+0

好吧,自從'電影has_many:照片'它結束了使用複數和添加照片作爲一個陣列:'photos_attributes:[{name:'bar'}]]) – Martin

+0

啊,是的,對不起。我已經更新了上面的代碼以反映出這個問題,以防其他人遇到此問題。祝你好運! – adimitri

0
movie = Movie.where(title: 'foo').first 
if movie.nil? 
    movie = Movie.new(title: 'foo') 
    movie.photos.build(name: 'bar') 
    movie.save 
else 
    movie.photos.create(name: 'bar') 
end 
+0

其實是的,我需要至少一個照片驗證。請參閱:http://stackoverflow.com/a/12962317/471313 – Martin

+0

@Martin查看更新的答案。 – varatis