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)  endendclass Thumbnail < ActiveRecord::Base  belongs_to :galleryendGiven the following data (as fixture):thumbnails.ymlone:  gallery: onetwo:  gallery:galleries.ymlone:  name: MyStringI 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) # falsegalleries(:one).thumbnails                           # [#<Thumbnail one>, #<Thumbnail two>]galleries(:one).thumbnails.include? thumbnails(:two) # trueIt 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.
Add existing models to a relation using nested attributes
ruby;unit testing;ruby on rails;active record
Couple of things to improve here:Firstly - do not use fixtures, use factories. There is a neat library allowing you to do this with ease called FactoryGirl (for rails you will need FactoryGirlRails). Having this in place you can define factories like:FactoryGirl.define do  factory :thumbnail do    name 'Thumbnail name if you have such a field'    other_field :other_value  endendAnd then use it as:thumbnail = FactoryGirl.create :thumbnailOne advantage of factories is that it does not load all the data into the database for each test, but rather allows you tell it what is needed instead. There are quite a lot of options you can add to your factories, like dynamic field values (useful when you have uniqueness validations), building parameters, building associated objects etc. All are well documented on gem github wiki.Secondly, accepts_nested_attributes_for already provides you with a method to assign objects using their ids:@model.children_ids << [1,2,3]or even modify the whole association in one go@model.children_ids = [1,2,3]This is usually more useful in terms of web forms. If you have a form where client can select multiple objects from a list from db, all you need to do is to name those fields children_ids and rails will take care of persisting the association.