验证has_many / new_record的父项是否存在?情况

时间:2013-11-18 00:04:15

标签: ruby-on-rails validation activerecord

class Game < ActiveRecord::Base
  has_many :moves
end

class Move < ActiveRecord::Base
  belongs_to :game
  belongs_to :user

  validates_presence_of :user
  validates_presence_of :game # validator in question
end

#####

game = Game.new
move = current_user.moves.build
game.moves << move
game.save # => false
game.errors.mesages # => {:"moves.game"=>["can't be blank"]}

game.save上,ActiveRecord会自动将新创建的游戏分配给移动。但是,validates_presence_of :game会抛弃它,因为在保存之前会检查所有验证(游戏和移动)。这完全有道理。

删除game上的move约束显然会让记录通过....但是我想保留它,因为大多数时间的动作是以更独立的方式创建的。例如:

move      = current_user.moves.build
move.game = @game
move.save

所以,我的问题:我是否应该继续删除该验证器,并确保始终在整个代码库中设置move.game?或者有一种神奇的方法可以保留它,并且仍然使用Game.new.moves << move

1 个答案:

答案 0 :(得分:1)

通过更多的研究,我发现这是一种神奇的方式。我只需要在关系的两边添加inverse_of个选项。不确定究竟如何帮助ActiveRecord知道如何传递验证器,但它确实有效!以下是更新的模型:

class Game < ActiveRecord::Base
  has_many :moves, inverse_of: :game
end

class Move < ActiveRecord::Base
  belongs_to :game, inverse_of: :moves
  belongs_to :user

  validates_presence_of :user
  validates_presence_of :game
end

#####

game = Game.new
move = current_user.moves.build
game.moves << move
game.save # => true

此答案包含:inverse_of解决方案:https://stackoverflow.com/a/4783112/2531850