2010-04-20 72 views
8

在rails中,當保存一個active_record對象時,它的關聯對象也將被保存。但has_one和has_many關聯在保存對象方面有不同的順序。保存活動記錄,保存關聯對象的順序是什麼?

我有三個簡單的模式:

class Team < ActiveRecord::Base 
    has_many :players 
    has_one :coach 
end 

class Player < ActiveRecord::Base 
    belongs_to :team 
    validates_presence_of :team_id 
end 

class Coach < ActiveRecord::Base 
    belongs_to :team 
    validates_presence_of :team_id 
end 

我預計,當team.save被調用時,團隊應該與其相關的教練和球員之前保存。

我用下面的代碼來測試這些模型:

t = Team.new 
team.coach = Coach.new 
team.save! 

team.save!返回true。

但在另一項測試:

t = Team.new 
team.players << Player.new 
team.save! 

team.save!提供了以下錯誤:

> ActiveRecord::RecordInvalid: 
> Validation failed: Players is invalid 

我想通了,team.save!按以下順序保存對象:1)的球員,2)團隊, 3)教練。這就是爲什麼我得到了錯誤:當一名球員被保存時,球隊還沒有一個ID,所以validates_presence_of :team_id失敗的球員。

有人可以向我解釋爲什麼物體按這個順序保存嗎?這對我來說似乎不合邏輯。

+0

使問題更加明確:當team.save!被調用,是否有可能在玩家對象之前將團隊對象保存到數據庫? – Shuo 2010-04-20 20:59:13

回答

0

你應該使用的 「validates_associated」 來實現這一目標

檢查Here

喜歡的東西下面沒有檢查雖然

class Team < ActiveRecord::Base 
    has_many :players 
    has_one :coach 
    validates_associated :players, :coach ###MOST IMPORTANT LINE 
end 

class Player < ActiveRecord::Base 
    belongs_to :team 
    validates_presence_of :team_id 
end 

class Coach < ActiveRecord::Base 
    belongs_to :team 
    validates_presence_of :team_id 
end 

在你的控制器

t = Team.new 

@coach = t.build_coach(:column1=> "value1", :column2=> "value2") # This create new object with @coach.team_id= t.id 
@players = t.players.build 

t.save#This will be true it passes the validation for all i.e. Team, COach & Player also save all at once otherwise none of them will get saved. 
+2

這仍然會引發ActiveRecord :: RecordInvalid。 – zetetic 2010-04-20 05:57:21

+0

請將您的代碼添加到「validates_associated」 – Salil 2010-04-20 06:08:17

+0

validates_associated僅驗證關聯模型本身是否有效,但不驗證關聯模型是否存在。爲此,您需要validates_presence_of。 有關詳細信息,請參閱http://github.com/rails/rails/blob/v3.0.0.beta.3/activerecord/lib/active_record/validations/associated.rb。 – 2010-04-20 17:52:57

-1

讓我們看看你的未通過測試:

t = Team.new 
team.players << Player.new 
team.save! 

添加一個新的玩家對team.players協會試圖設置在玩家TEAM_ID右邊有第2行這只是如何< <運營商的作品。當您保存球隊時它不會更新,因此即使球隊先保存,球員仍然有一個空的team_id。在這種情況下,您可以輕鬆地通過交換第2行和第3行來解決此問題。