Rails updates update associations without saving to the database

I want to see what the model will look like when saving without currently saving the database.

I use @event.attributes = because it assigns but does not store the attributes for @event in the database.

However, when I also try to assign an association to audiences , Rails inserts new entries into the audiences_events connection table. Not cool. Is there a way to see how these new associations will look without inserting them into the connection table?

Model

 class Event < ActiveRecord::Base has_and_belongs_to_many :audiences # And vice versa for the Audience model. end 

Controller

 class EventsController < ApplicationController def preview @event = Event.find(params[:id]) @event.attributes = event_params end private def event_params params[:event].permit(:name, :start_time, :audiences => [:id, :name] end end 

Possible solutions?

Possible solutions that I thought about, but don't know how to do this:

  • Using some method that assigns associations but is not saved.
  • disabling all database entries for this one action (I don't know how to do this).
  • Rollback all database changes at the end of this action

Any help with them would be great!

UPDATE:
After reading the wonderful answers below, I wrote this class of service that assigns non-nested attributes to the Event model, and then calls collection.build for each of the nested parameters. I made a little entity. I am pleased to receive comments / suggestions.

https://gist.github.com/jameskerr/69cedb2f30c95342f64a

+7
ruby ruby-on-rails activerecord ruby-on-rails-4 rails-activerecord
source share
2 answers

In these docs you have:

When are objects saved?

When you assign the has_and_belongs_to_many association object, this object is automatically saved (to update the connection table). If you assign multiple objects in a single expression, they are all saved.

If you want to assign the has_and_belongs_to_many association object without saving the object, use the collection.build method.

Here is a good answer for Rails 3 that addresses some of the same issues

Rails 3 has_and_belongs_to_many: how to assign related objects without storing them in the database

+4
source share

Deals

Creating transactions is pretty straight forward:

 Event.transaction do @event.audiences.create! @event.audiences.first.destroy! end 

or

 @event.transaction do @event.audiences.create! @event.audiences.first.destroy! end 

Pay attention to the use of the "bang" create! methods create! and destroy! , unlike create , which returns false create! , will throw an exception if it fails and causes the transaction to be rolled back.

You can also manually roll back at any point in the transaction by raising ActiveRecord::Rollback .

Build

build creates a new linked object without saving.

 event = Event.new(name: 'Party').audiences.build(name: 'Party People') event.save # saves both event and audiences 
+4
source share

All Articles