In console:
List.update(1, :updated_at=>Time.now)
In log file:
SELECT * FROM lists WHERE (lists.id
= 1)
SQL (0.000000) BEGIN
List Update (0.000000) UPDATE lists SET created_at
= ‘2007-08-10
23:15:36’, desc
= NULL, public
= 0, user_id
= NULL, updated_at
=
‘2007-08-19 22:28:21’, name
= ‘qwe’ WHERE id
= 1
SQL (0.031000) COMMIT
Why does every update fires a select first?
This seems very inefficient. Is there a work around? is this an accepted
fact in the rails community? For every write there will be at least one
read, how come this is the default behaviour. Should i just accept this
as a expense of using rails?
Any help is appreciated.
Jigar G. wrote:
In console:
List.update(1, :updated_at=>Time.now)
In log file:
SELECT * FROM lists WHERE (lists.id
= 1)
SQL (0.000000) BEGIN
List Update (0.000000) UPDATE lists SET created_at
= ‘2007-08-10
23:15:36’, desc
= NULL, public
= 0, user_id
= NULL, updated_at
=
‘2007-08-19 22:28:21’, name
= ‘qwe’ WHERE id
= 1
SQL (0.031000) COMMIT
Why does every update fires a select first?
This seems very inefficient. Is there a work around? is this an accepted
fact in the rails community? For every write there will be at least one
read, how come this is the default behaviour. Should i just accept this
as a expense of using rails?
Any help is appreciated.
Interesting. The deeper and deeper I get into Rails, the less and less
it does – it seems. Still, its better than what I could do on my own.
My guess is that it is not “accepted”. There is a constant stream of
improvements.
Took a look at the docs, this is the accepted behaviour:
Finds the record from the passed id, instantly saves it with the
passed attributes (if the validation permits it), and returns it. If
the save fails under validations, the unsaved object is still
returned.
So it does quite a bit for you: finds the record, runs the model
validations, saves it if validations pass, or gives original record if
validations failed. In this context ‘update’ doesn’t mean ‘update the
database record’ it really means ‘update the model object and make
sure it is valid’. To do this it must hydrate the object.
Rich C.
I understand that it is acceptable as far as the docs are concerned. But
do we really need this behaviour all the time? is it required to fetch
all the data, when performing validations? and how many times we need
the record we updated back?
Doesn’t this seem, inefficient? I wish this post would get attention of
DHH.
Rich C wrote:
Took a look at the docs, this is the accepted behaviour:
Finds the record from the passed id, instantly saves it with the
passed attributes (if the validation permits it), and returns it. If
the save fails under validations, the unsaved object is still
returned.
So it does quite a bit for you: finds the record, runs the model
validations, saves it if validations pass, or gives original record if
validations failed. In this context ‘update’ doesn’t mean ‘update the
database record’ it really means ‘update the model object and make
sure it is valid’. To do this it must hydrate the object.
Rich C.
There is a documented workaround for this. update_attribute does not
load the record and DOES NOT DO VALIDATION. I humbly believe this is
errent behavior, but I have lost this fight too many times to try again.
(I’m not as good looking as DHH)
From the docs –
ubdate_attribute:
Updates a single attribute and saves the record. This is especially
useful for boolean flags on existing records. Note: This method is
overwritten by the Validation module that‘ll make sure that updates made
with this method doesn‘t get subjected to validation checks. Hence,
attributes can be updated even if the full object isn‘t valid.
Jigar G. wrote:
I understand that it is acceptable as far as the docs are concerned. But
do we really need this behaviour all the time? is it required to fetch
all the data, when performing validations? and how many times we need
the record we updated back?
Doesn’t this seem, inefficient? I wish this post would get attention of
DHH.
Rich C wrote:
Took a look at the docs, this is the accepted behaviour:
Finds the record from the passed id, instantly saves it with the
passed attributes (if the validation permits it), and returns it. If
the save fails under validations, the unsaved object is still
returned.
So it does quite a bit for you: finds the record, runs the model
validations, saves it if validations pass, or gives original record if
validations failed. In this context ‘update’ doesn’t mean ‘update the
database record’ it really means ‘update the model object and make
sure it is valid’. To do this it must hydrate the object.
Rich C.
This issue comes up a lot. First of all, retrieving the record before
update is important to avoid race conditions (see optimistic locking and
LOCK VERSION).
You could issue the SQL statement yourself…
List.connection.execute "update lists set updated_at = #{Time.now.to_s
(:db)}’
I prefer to let Rails handle it for me so I can take advantage of
lock_version.