在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 :(得分: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.
答案 1 :(得分:-1)
让我们来看看你的失败测试:
t = Team.new
team.players << Player.new
team.save!
向team.players关联添加一个新玩家尝试在第2行设置玩家的team_id。这就是&lt;&lt;操作员工作。保存团队时不会更新,因此即使先保存团队,玩家仍然拥有null team_id。在这种情况下,您可以通过交换第2行和第3行轻松解决它。