Cameron Martin
Cameron Martin

Reputation: 6012

Rails validations failing due to other side of association not being set

Problem

class Match
  has_many :items
end

class Item
  belongs_to :match
  validates :match, presence: true
end

class ItemBuilder
  def self.build
    5.times.map { |_| Item.new }
  end
end

class MatchBuilder
  def self.build
    Match.new(items: ItemBuilder.build)
  end
end

match = MatchBuilder.build
match.save # Validation fails because Item#match isn't set!

It seems to me that rails should set the Item#match association when assigning Match#items, but this is not the case.

In reality, the ItemBuilder builds Items from information from an API. I'd prefer it not to have knowledge of where those Items are going to be put, so I can't pass the match into ItemBuilder.

I'd also prefer to not have the Matchbuilder aware of the internals of the Items returned from ItemBuilder, so I can't do

class MatchBuilder
  def self.build
    items = ItemBuilder.build
    match = Match.new(items: items)
    items.each do |item|
      item.match = match
    end
  end
end

Is there any way of getting around this, without explicitly setting Item#match?

Possible Solutions

Upvotes: 0

Views: 45

Answers (1)

Magnuss
Magnuss

Reputation: 2310

I'd do something like this:

match = Match.new
5.times { match.items.build }
match.save

Not sure if autosave: true is needed for items association in this case.

Upvotes: 2

Related Questions