Reputation: 1577
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"]}
On game.save
, ActiveRecord will automatically assign the newly created game to the move. validates_presence_of :game
throws this off, though, since all the validations (for both game and move) are checked before save. Which totally makes sense.
Removing the game
constraint on move
obviously lets the records go through.... BUT I'd like to keep it around since most of the time moves are created in a more standalone fashion. For instance:
move = current_user.moves.build
move.game = @game
move.save
So, my question: Should I just go ahead and remove that validator, and just ensure move.game
is always set throughout the codebase? Or is there a magic way to keep it, and still utilize Game.new.moves << move
Upvotes: 1
Views: 248
Reputation: 1577
With a bit more research, I figured out there IS a magic way. I just needed to add inverse_of
options to both sides of the relationship. Not sure exactly how that helps ActiveRecord know how to pass the validator, but it works! Here are the updated models:
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
This answer had the :inverse_of
solution: https://stackoverflow.com/a/4783112/2531850
Upvotes: 1