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?
Persisted means the object has been saved in the database. You can only call it on ActiveRecord objects.
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.
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.
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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With