I needed to add existing models to a has-many relation using nested attributes so I overwrote thumbnails_attributes=
:
class Gallery < ActiveRecord::Base
has_many :thumbnails, dependent: :nullify
accepts_nested_attributes_for :thumbnails
def thumbnails_attributes=(thumbnails_attributes)
ids = thumbnails_attributes.map { |t| t['id'] }
(ids - thumbnail_ids).each do |id|
thumbnail = Thumbnail.find id
thumbnails << thumbnail
end
super(thumbnails_attributes)
end
end
class Thumbnail < ActiveRecord::Base
belongs_to :gallery
end
Given the following data (as fixture):
thumbnails.yml
one:
gallery: one
two:
gallery:
galleries.yml
one:
name: MyString
I can now run:
galleries(:one).update(thumbnails_attributes: ['id' => thumbnails(:two).id])
and galleries(:one).thumbnails
will return both thumbnails.
While it works pretty well, I wanted to ask for reviews and ways to improve/clean this code.
The only issue I have is with include?
(which is used by assert_includes
in my tests):
galleries(:one).update(thumbnails_attributes: ['id' => thumbnails(:two).id])
galleries(:one).thumbnails.include? thumbnails(:two) # false
galleries(:one).thumbnails # [#<Thumbnail one>, #<Thumbnail two>]
galleries(:one).thumbnails.include? thumbnails(:two) # true
It looks like I have to reload the relation for include?
to work, but I haven't found a fix nor a way to properly test it.
galleries(:one).thumbnails.to_a.include? thumbnails(:two)
works, include?
doesn't appear to load the association.