保存活动记录,保存关联对象的顺序是什么?

Shu*_*huo 8 activerecord ruby-on-rails

在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
Run Code Online (Sandbox Code Playgroud)

我希望在team.save被召唤时,球队应该在其关联的教练和球员之前得到保存.

我使用以下代码来测试这些模型:

t = Team.new
team.coach = Coach.new
team.save!
Run Code Online (Sandbox Code Playgroud)

team.save! 返回true.

但在另一个测试中:

t = Team.new
team.players << Player.new
team.save!
Run Code Online (Sandbox Code Playgroud)

team.save! 给出以下错误:

> ActiveRecord::RecordInvalid:
> Validation failed: Players is invalid
Run Code Online (Sandbox Code Playgroud)

我发现team.save!按以下顺序保存对象:1)玩家,2)团队,3)教练.这就是我收到错误的原因:当玩家被保存时,团队还没有id,所以validates_presence_of :team_id玩家失败了.

有人可以向我解释为什么按此顺序保存对象?这对我来说似乎不合逻辑.

Sal*_*lil 0

您应该使用“validates_linked”来完成此任务

检查这里

不过,就像没有检查一样

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
Run Code Online (Sandbox Code Playgroud)

在你的控制器中

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.
Run Code Online (Sandbox Code Playgroud)

  • 这仍然会引发 ActiveRecord::RecordInvalid。 (2认同)