Not updating the updated_at field

This is for Rails 3.1.1

I have a field called last_seen in a model. This field will be updated
when the something about the record is seen in the real world (don't
worry about this part)

So I go x.update_attribute(:last_seen, Time.now) and the following happens is

UPDATE "blah" SET "last_seen" = '2012-10-23 08:57:46.179288',
"updated_at" = '2012-10-23 08:57:54.872808' WHERE "blah"."id" = 2673

Now, just for this one attribute, I would like the updated_at field to
be unmolested. Is there some way of updating the last_seen field
without ActiveRecord updating the updated_at field?

This is for Rails 3.1.1

I have a field called last_seen in a model. This field will be updated
when the something about the record is seen in the real world (don't
worry about this part)

So I go x.update_attribute(:last_seen, Time.now) and the following happens is

UPDATE "blah" SET "last_seen" = '2012-10-23 08:57:46.179288',
"updated_at" = '2012-10-23 08:57:54.872808' WHERE "blah"."id" = 2673

Now, just for this one attribute, I would like the updated_at field to
be unmolested. Is there some way of updating the last_seen field
without ActiveRecord updating the updated_at field?

So you want to update a record without setting update_at? I suggest
that this is not a good idea as it subverts the purpose of updated_at.
If you want a field that only records the date when the record is
updated under certain circumstances then it would probably be better
to add a new field that you maintain yourself.

If you feel you really want to do it then you use raw sql to update the record.

Colin

The problem is that the updated_at field is useful for other functions
but the last_seen field being updated is causing the updated_at field
to update and records are being processed if they have been updated
since the system was last checked (I hope I explained that correctly).
Basically the records are being polled for changes based on the
updated_at time. The last_seen field is causing the records to appear
to be updated when they are not, at least not in any way that we are
interested in.

Creating a 'real_updated_at' field would be confusing by itself and
require code changes to make sure that it always gets updated when
anything but the last_seen field is updated (not a big problem I know
but less than obvious to anyone reading the code).

Another alternative that I can see is a new table for last_seen that
has a strict one to one relationship with the master record. Which
normalisation would say should be part of the master record, just to
get round the updated_at field.

I suspect that raw SQL will be the way round this. I was just hoping
to make this transparent (you just know someone will see the raw SQL
and not read the comments and 'improve' the code).

The problem is that the updated_at field is useful for other functions

but the last_seen field being updated is causing the updated_at field

to update and records are being processed if they have been updated

since the system was last checked (I hope I explained that correctly).

Basically the records are being polled for changes based on the

updated_at time. The last_seen field is causing the records to appear

to be updated when they are not, at least not in any way that we are

interested in.

Creating a ‘real_updated_at’ field would be confusing by itself and

require code changes to make sure that it always gets updated when

anything but the last_seen field is updated (not a big problem I know

but less than obvious to anyone reading the code).

Another alternative that I can see is a new table for last_seen that

has a strict one to one relationship with the master record. Which

normalisation would say should be part of the master record, just to

get round the updated_at field.

I suspect that raw SQL will be the way round this. I was just hoping

to make this transparent (you just know someone will see the raw SQL

and not read the comments and ‘improve’ the code).

this may help http://stackoverflow.com/questions/1386490/manually-set-updated-at-in-rails

or you can skip using raw sql and use AR’s update_column method

http://api.rubyonrails.org/classes/ActiveRecord/Persistence.html

The problem is that the updated_at field is useful for other functions
but the last_seen field being updated is causing the updated_at field
to update and records are being processed if they have been updated
since the system was last checked (I hope I explained that correctly).
Basically the records are being polled for changes based on the
updated_at time. The last_seen field is causing the records to appear
to be updated when they are not, at least not in any way that we are
interested in.

Creating a 'real_updated_at' field would be confusing by itself and
require code changes to make sure that it always gets updated when
anything but the last_seen field is updated (not a big problem I know
but less than obvious to anyone reading the code).

I think you have the name wrong. The normal updated_at is the 'real'
updated at time. You are asking for a non-standard updated_at field.
The code would go in a before_save filter probably. I think it could
be more confusing for anyone reading the code to have an updated_at
field which did not reflect the actual time the record was updated
rather than a new one which is only updated under certain
circumstances.

Another alternative that I can see is a new table for last_seen that
has a strict one to one relationship with the master record. Which
normalisation would say should be part of the master record, just to
get round the updated_at field.

I suspect that raw SQL will be the way round this. I was just hoping
to make this transparent (you just know someone will see the raw SQL
and not read the comments and 'improve' the code).

An additional field would solve all the problems.

Colin

The problem is that the updated_at field is useful for other functions
but the last_seen field being updated is causing the updated_at field
to update and records are being processed if they have been updated
since the system was last checked (I hope I explained that correctly).
Basically the records are being polled for changes based on the
updated_at time. The last_seen field is causing the records to appear
to be updated when they are not, at least not in any way that we are
interested in.

This feels like you are mixing metaphors. The act of seeing the record is external to the record, or its current state of having been edited at a particular time. If you had a separate object that encapsulated the act of viewing one of these objects, then the max created_at of that external "I saw it" object would be your last-viewed time. This would also let you record views for other types of objects, should you need that.

Walter

try

x.record_timestamps = false

x.update_attribute :last_seen, Time.now

You may wish to reset record_timestamps to its original value if you’re going to keep using that particular instance for other purposes, where you will want to record updated at. If you do this a lot you could write something like

def without_timestamps

begin

old = record_timestamps

self.record_timestamps = false

yield

ensure

self.record_timestamps = old

end

end

and then x.without_timestamps {x.update_attribute :last_seen, Time.now}

Fred

update_column will do exactly what you’re looking for, and has the advantage of not being on the short list to go away in Rails 4.1 like update_attribute. :slight_smile:

–Matt Jones