Reputation: 3311
I am having trouble updating multiple columns properly with rails activerecords. I want to use something like update which basically gets updated_at updated, but i just cant pass multiple column. I could use update_all but it doesnt update updated_at with the current timestamp.
Here's what i'ved tried:
this doesnt work: (only takes in payment_total but not the rest)
retval = @invoice.update(:payment_total => 20,
:due_amount => 10,
:data => clonedata.to_json)
:data - this is actually a json field
output:
nothing
this works:
retval = Invoice.where(:id => @invoice.id).update_all(:payment_total => 20,
:due_amount => 10,
:data => clonedata.to_json)
output: (notice it doesnt update the "updated_at" field)
SQL (1.1ms) UPDATE "invoices" SET "payment_total" = '30.00', "due_amount" = '86.00', "data" = ‘{“name”:”Test}' WHERE "invoices"."id" = 6
a single param would work:
retval = @invoice.update(:payment_total => 20)
output:
UPDATE "invoices" SET "due_amount" = $1, "updated_at" = $2 WHERE "invoices"."id" = 6
[["due_amount", "86.0"], ["updated_at", "2014-05-18 03:48:49.718692"]]
now how do i use something similar to update multiple columns while updated_at also gets the current timestamp updated ?
Upvotes: 3
Views: 9116
Reputation: 136
Updates all, This method constructs a single SQL UPDATE statement and sends it straight to the database. It does not instantiate the involved models and it does not trigger Active Record callbacks or validations. Values passed to update_all will not go through ActiveRecord's type-casting behavior. It should receive only values that can be passed as-is to the SQL database.
As such, it does not trigger callbacks nor validations - and timestamp update is made in a callback.update_at is a call back
Upvotes: -1
Reputation: 76774
When you mention you want to update multiple columns
- I presume this would be for a single record?
This line will update a collection
response (.where
returns a collection
rather than single object
):
retval = Invoice.where(:id => @invoice.id).update_all(:payment_total => 20,
:due_amount => 10,
:data => clonedata.to_json)
If you're looking to update a single record, I would use the update
method like this:
@invoice = Invoice.update(params[id], payment_total: "20", due_amount: "10", data: clonedata.to_json)
Upvotes: 4
Reputation: 4296
#update
is the method you want for this. If it's not working correctly, that means you're not calling it the way you think you are. Maybe try calling #update!
and see if you get an exception raised?
Upvotes: -1