Lighthouse has a new layout. Prefer the old one? Return to the old layout, and switch back any time from the link at the top of each page.

This project is archived and is in readonly mode.

New update_attribute doesn't work with associations

#5158

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.

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

State: resolved
Milestone: none
Assigned to: nobody
Importance: Low

Activity

  1. Neeraj Singh
    Neeraj Singh
    • 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.

    July 20th, 2010 @ 11:58 AM

  2. Mateusz Drożdżyński
    Mateusz Drożdżyński

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

    July 20th, 2010 @ 12:01 PM

  3. Mateusz Drożdżyński
    Mateusz Drożdżyński

    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?

    July 20th, 2010 @ 12:08 PM

  4. Neeraj Singh
    Neeraj Singh

    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.

    July 20th, 2010 @ 12:50 PM