Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Rails: How do I call `self.save` in my model and have it persist in the database?

I'm trying to keep model logic within my model, but I can't get it to perform modifications on itself and have them persist in the database.

In my controller:

@article.perform_some_calulcations!

In my model:

def perform_some_calculations!
  self.foo.gsub!(/regexp/, 'string')
  self.save
end

If I drop debugger statements into my method and after my call to it in the controller, @article.foo has the correct value. However, when I continue, it doesn't persist in the database and webrick doesn't report any UPDATE statements.

What's going wrong? I don't know if I've ever had to do this before, but surely it's possible right?

like image 776
nfm Avatar asked Oct 28 '10 02:10

nfm


People also ask

What does persisted mean in rails?

Persisted means the object has been saved in the database. You can only call it on ActiveRecord objects.

What is the use of touch in rails?

In rails touch is used to update the updated_at field for persisted objects. But if we pass other attributes as arguments, it will update those fields too along with updated_at . Even it will update non-date-time fields if passed as arguments.

What does Rails generate model do?

A Rails Model is a Ruby class that can add database records (think of whole rows in an Excel table), find particular data you're looking for, update that data, or remove data. These common operations are referred to by the acronym CRUD--Create, Remove, Update, Destroy.


1 Answers

Your problem was that if you modify an attribute "in place", this means: without assigning it a new value, then Rails will think that there is nothing new to be saved, so it "optimizes" the save away.

Each write accessor of your attribute will set a flag, so the save method will know that it should check whether the current value really differs from the value read from the database. That's why self.foo = self.foo.gsub(/regexp/, 'string') works (note that the exclamation mark is not necessary here).

If you need to modify an attribute "in place", for example with gsub! or replace, use:

def perform_some_calculations!
  foo_will_change!
  self.foo.gsub!(/regexp/, 'string')
  self.save
end
like image 140
Arsen7 Avatar answered Oct 02 '22 14:10

Arsen7