This project is archived and is in readonly mode.

#5158 ✓resolved
Mateusz Drożdżyński

New update_attribute doesn't work with associations

Reported by Mateusz Drożdżyński | July 20th, 2010 @ 11:31 AM

Previous implementation of update_attribute:

def update_attribute(name, value)
  send("#{name}=", value)
  save(false)
end

worked just fine with associations.

The one present in current master breaks this support:

Consider this call:

article.update_attribute(:user, user)

Let's go through the method definition:

def update_attribute(name, value)     
  changes = record_update_timestamps || {}

  if name
    name = name.to_s
    send("#{name}=", value) # this works fine, sets article.user to user
    changes[name] = read_attribute(name) # this doesn't work; read_attribute returns nil for associations.
  end

  @changed_attributes.except!(*changes.keys)
  primary_key = self.class.primary_key
  self.class.update_all(changes, { primary_key => self[primary_key] }) == 1 # this doesn't work either; tries to update a column (user) which doesn't exist (should be updating user_id instead).
end

It either needs to be made clear that update_attribute does not work for associations (and preferably raise an exception if you try to do so, complaining that :user is not a database column in this example) or support it by detecting that you're passing an association and updating _id columns instead.

Comments and changes to this ticket

  • Neeraj Singh

    Neeraj Singh July 20th, 2010 @ 11:58 AM

    • State changed from “new” to “resolved”
    • Importance changed from “” to “Low”

    My bad. I should have updated the doc after the refactoring.

    Doc has been updated http://github.com/lifo/docrails/commit/767de13ff4a19a53d3fe99edb555...

    Thanks for the feedback.

  • Mateusz Drożdżyński

    Mateusz Drożdżyński July 20th, 2010 @ 12:01 PM

    What was the reason for not supporting associations? Is this a design decision or simply something that is yet to be added?

  • Mateusz Drożdżyński

    Mateusz Drożdżyński July 20th, 2010 @ 12:08 PM

    Plus, regardless of the rationale behind it, shouldn't it raise an exception when you're trying to do so as opposed to going all the way through with the database query?

  • Neeraj Singh

    Neeraj Singh July 20th, 2010 @ 12:50 PM

    update_attribute was meant for sure shot way of updating a column. For example after sending an email to a user you want to mark that email has been sent to user. You don't want any validation or before_save callback to abort the operation. In one case employer sent 3300 emails to same person because before_save operation returned false.

    In 2-3 people used update_attribute to update association because update_attribute was using save and that operation was allowed. However that was not how update_attribute was supposed to be used. In rails3 scope of update_attribute has been limited.

    Regarding raising the exception I did not think it was that big a deal because it will be caught during development time. I might be wrong on that.

Create your profile

Help contribute to this project by taking a few moments to create your personal profile. Create your profile »

<h2 style="font-size: 14px">Tickets have moved to Github</h2>

The new ticket tracker is available at <a href="https://github.com/rails/rails/issues">https://github.com/rails/rails/issues</a>

Pages