Updating only one field


#1

At present, I use an update like this to set the user’s last login time:

authenticated_user.update_attribute(:last_login, Time.now)

However, this calls the following, updating all fields:

UPDATE users SET last_login = ‘2006-05-02 13:27:41’, hashed_password
= …

Is there any way I can tell ActionRecord to only update the one field?
I don’t really want the hashed_password (and other) fields sent back to
the database if possible. If there is a reason rails does it like this
that I’m missing, it would be good to hear what.

Thanks.


#2

authenticated_user.last_login = Time.now
authenticated_user.save

David wrote:

At present, I use an update like this to set the user’s last login time:

authenticated_user.update_attribute(:last_login, Time.now)

However, this calls the following, updating all fields:

UPDATE users SET last_login = ‘2006-05-02 13:27:41’, hashed_password
= …

Is there any way I can tell ActionRecord to only update the one field?
I don’t really want the hashed_password (and other) fields sent back to
the database if possible. If there is a reason rails does it like this
that I’m missing, it would be good to hear what.

Thanks.


#3

Steve K. wrote:

David wrote:

Is there any way I can tell ActionRecord to only update the one field?
I don’t really want the hashed_password (and other) fields sent back to
the database if possible. If there is a reason rails does it like this
that I’m missing, it would be good to hear what.

authenticated_user.last_login = Time.now
authenticated_user.save

I believe I tried this, but the save fails (tested with .save or
logger.info ‘failed :(’). Is there any way to find out why?

I am assuming it fails because there is a validator on the password
attribute, which is an attr_accessor that is only filled during create
or change_password.

Cheers for your answer.


#4

try @user.update_attribute()

adam


#5

On May 2, 2006, at 09:31 PM, Jean-François wrote:

authenticated_user.save_without_validation
I would say you definitely don’t want to do this. While I think it’s
a good thing that save_without_validation is there in ActiveRecord, I
don’t think I would ever use it in a production application. In fact,
I might only use it in a Unit Test, but even there, I’m not sure when
I would use it.

The good news is, there are ways to update attributes without needing
to perform a save action on the whole model object. The OP should be
able to just do:

authenticated_user.update_attribute(:last_login, Time.now)

I believe someone posted about update_attribute, but I don’t believe
that post had a direct example pertaining to the OP’s code…

-Brian


#6

On 5/2/06, Brian H. removed_email_address@domain.invalid wrote:

The good news is, there are ways to update attributes without needing
to perform a save action on the whole model object. The OP should be
able to just do:

authenticated_user.update_attribute(:last_login, Time.now)

I believe someone posted about update_attribute, but I don’t believe
that post had a direct example pertaining to the OP’s code…

Except, using update_attributes will still do a SQL Update for the
whole record. From the log of a little test app I have:

Book Update (0.003085) UPDATE books SET “author” = ‘Bill Writer
klj ;lkj’, “title” = ‘new title’ WHERE id = 2

That was after I did in the console:

b = Book.find(2)
b.update_attribute(:title, “new title”)

FYI…


#7

2006/5/2, David removed_email_address@domain.invalid:

I am assuming it fails because there is a validator on the password
attribute, which is an attr_accessor that is only filled during create
or change_password.

Just an idea, try :

authenticated_user.last_login = Time.now
authenticated_user.save_without_validation

-- Jean-François.

#8

On May 2, 2006, at 11:21 PM, John T. wrote:

Except, using update_attributes will still do a SQL Update for the
whole record. From the log of a little test app I have:

Book Update (0.003085) UPDATE books SET “author” = ‘Bill Writer
klj ;lkj’, “title” = ‘new title’ WHERE id = 2

That was after I did in the console:

b = Book.find(2)
b.update_attribute(:title, “new title”)

Hmm… well. I stand (or type :wink: corrected. I wasn’t aware that it
did a full object update, simply including the new data. I though it
did just a single column. I suppose I can see why that’s the case,
but the AWDR book certainly leads you to believe it will simply
update that attribute.

That being said, I still don’t like the idea of designing a model
method that deliberately defeats the model’s validation. Just feels
wrong to me, but it definitely looks like that is the way to go, if
that’s what you have a need to do…

-Brian


#9

Hi Brian,

you mention that you wouldn’t use save_without_validation and then
propose using update_attribute.

I’m guessing that you’re not aware that update_attribute (the
singular version of the method) does not trigger validation - check
the API docs for more information.

Regards,
Trevor


#10

On May 3, 2006, at 12:06 AM, Trevor S. wrote:

you mention that you wouldn’t use save_without_validation and then
propose using update_attribute.

Yes I did. I said that, because I don’t like the idea of explicitly
telling the entire model to save itself, but skip all the validation
that I’ve added to make sure that a full model object is valid. At
least, not in my production code.

I’m guessing that you’re not aware that update_attribute (the
singular version of the method) does not trigger validation - check
the API docs for more information.

Actually, I did read that, and that’s pretty much what I was trying
to say in my message. However, I managed to confuse “save the whole
model object” with “run validation on the model object when saving”.
As you (and the API docs :wink: point out, those aren’t the same thing.
Thanks for clearing up what I managed to get quite confused about.

I suppose it’s a style/philosophical thing, but I have no problem
with the implicit “skipping” of validation that comes from using
update_attribute. That’s a designed feature of that method. But
save_without_validation just gives me a weird feeling. Not sure I can
explain it better than that…

-Brian