gwnp
gwnp

Reputation: 1216

Rails - detach model from database session

I came across a scenario where in other languages I would detach the model object from the transaction then I can alter it all I want without worry of an automatic-update to the record.

Question

  1. Does rails not support attaching\detaching a model object?

  2. What is the alternative, just duplicate the object?

EDIT

Scenario

We are reading models out of the database and we want to make changes to them that will not be persisted to the database at the end of the transaction. In Hibernate\JPA etc you detach the model (Entity) and no changes will be persisted.

Now you may ask why not use Model.dup? The answer is that we still need the id of the model but as soon as you assign the id, rails believes this instance is now the model and updates the record at the end of the transaction.

Thanks

Upvotes: 4

Views: 525

Answers (2)

Alexander Presber
Alexander Presber

Reputation: 6625

You can totally change Rails model instance attributes without persisting the changes.

There are a couple of methods to change model attributes, some of which do automatically persist the changes to the DB and others just change the attribute values of the in-memory instance.

You may want to try using #assign_attributes or #<attribute>= from the above list. Only after explicitly calling #save afterwards, the changes will be saved to the database.

Upvotes: 2

Phil
Phil

Reputation: 2807

As stated in a previous answer, you can update instance attributes without persisting them (by avoiding self.save for example). But if you want to be sure, consider the following that uses a validation to check for a flag attribute being nil (or blank):

attr_accessor :prevent_save
validates :prevent_save, absence: true

def prevent_save!
  self.prevent_save = true
end

def do_something_safely

  prevent_save!

  self.other_attr = 'abc'

end

def accidentally_save
  # if prevent_save! has been previously called, 
  # validations will fail, and save! will raise an exception
  self.save!
end

Upvotes: 0

Related Questions