【问题标题】:Saving an active record, in what order are the associated objects saved?保存活动记录,关联对象的保存顺序是什么?
【发布时间】:2010-04-20 03:20:14
【问题描述】:

在 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! 返回真。

但在另一个测试中:

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 在玩家中失败。

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

【问题讨论】:

  • 使问题更明确:当 team.save!被调用,是否可以在玩家对象之前将团队对象保存到数据库中?

标签: ruby-on-rails activerecord


【解决方案1】:

您应该使用“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.

【讨论】:

  • 这仍然会引发 ActiveRecord::RecordInvalid。
  • validates_associated 仅验证关联模型本身是否有效,但不验证关联模型是否存在。为此,您需要 validates_presence_of。有关详细信息,请参阅github.com/rails/rails/blob/v3.0.0.beta.3/activerecord/lib/…
  • 你能把球员和球队联系起来吗?那仍然通过验证吗?谢谢。
【解决方案2】:

让我们看看你的失败测试:

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

将新玩家添加到 team.players 关联会尝试在第 2 行设置玩家的 team_id。这就是

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-12-04
    • 2021-04-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多