Consider this scenario:
- butterfly = Butterfly.create(:color='blue')
- Butterfly.update_all(:color='red')
At this point, as expected, butterfly (in memory) is blue while the corresponding database object is red. Now try to update the database entry
- butterfly.update_attributes(:size=>'big')
The result is that the size attribute is updated but the color is not. We're left with a situation where, even after a successful save or up开发者_JS百科date_attributes, the database does not match the object in memory. In fact, even butterfly.update_attribute(:color, 'blue')
is not enough to force a change in the database! The only way I see to force is the change is by first updating the attribute to something else (butterfly.update_attribute(:color,'anything')
) and then changing it back to the original value.
Is this the way things are supposed to be?
Sort-of.
Model.update_all
issues an update query directly to the underlying database; it doesn't update any instances you already have in memory. Similarly, instance.update_attributes
only updates—it doesn't re-fetch from the database, as it assumes that the instance has the most up-to-date attribute values already.
This usually works in Rails, instances are generally short-lived: they only exist within the scope of the request, and in most cases, they're being operated on directly.
In the situation you describe above, you need an extra step—Model#reload
will do what you want:
# create our instance
@butterfly = Butterfly.create(color: 'blue') # => #<Butterfly id: 100, color: 'blue'>
Butterfly.update_all(color: 'red')
# We now have a mis-match between our instance and our database. Our instance
# is still blue, but the database says it should be red. Reloading it...
@butterfly.reload # => #<Butterfly id: 100, color: 'red'>
# And we can now re-update our butterfly
@butterfly.update_attributes(size: 'big') # => #<Butterfly id: 100, color: 'red', size: 'big'>
If you're using update_all
, it's a good idea to see if it's possible to structure your code so that it occurs before you load instances.
精彩评论