#109
May 21, 2008

Tracking Attribute Changes

Rails 2.1 keeps track of the changes you make to a model's attributes. It also allows you to see what the previous value was. But watch out for the gotcha! See this episode for details.
Download (8.1 MB, 7:26)
alternative download for iPod & Apple TV (7.9 MB, 7:26)

Update: Partial updates are no longer enabled by default in Rails 2.1 as you can see in this commit. Now you can set them in your environment config if you want.

Resources

# config/initializers/active_record_settings.rb
ActiveRecord::Base.partial_updates = true

# change tracking methods
p.changed?
p.changed
p.changes
p.name_changed?
p.name_was
p.name_change
p.name_will_change!

RSS Feed for Episode Comments 68 comments

1. Rymaï May 21, 2008 at 05:13

Cool feature! Very useful!

But use it with care : http://www.dcmanges.com/blog/rails-21-partial-updates-may-create-invalid-records


2. DBA May 21, 2008 at 06:05

Another useful webcast, as usual.

Thanks Ryan.


3. zul May 21, 2008 at 06:31

Thank u so much for useful casts :)


4. Tom Harrison May 21, 2008 at 08:13

These new features rock, as does your RailsCast.

I am a little dubious as to the wisdom of having partial updates as a default, however. Sure, when a record contains BLOBs or many large text fields it may make sense. But in most cases I'll bet the benefit is negligible.

@Rymai's link already points out the new risk of data consistency issues (it's worth reading!).

It seems to me that model-level syntax to turn partial updates off or on conditionally would be smarter. For example:

partial_update :unless => { :termination_date.changed? || :eligibility.changed? }

or

full_update :if => {
:termination_date.changed? || :eligibility.changed? }

Anyway, it's worth thinking about the consistency issue. The case may be unlikely, but it introduces a data-level issue in the name of dubious claims of performance increase.


5. Ryan Bates May 21, 2008 at 09:22

@Rymaï, thanks, I added the link to the show notes.

@Tom, I'm a little surprised partial updates are on by default in new 2.1 projects as well. I could see it causing some tricky bugs.

Your idea of being able to change this setting on a case by case basis makes sense. I look at it as more of a performance improvement which can be applied if you have a model with BLOBs or index columns. I recommend making a post on the rails core mailing list about this if there isn't one already.


6. Jeremy May 21, 2008 at 11:06

@Tom:

It is amazing to me how cool the rails community is. I have wondered over and over how Rails can have so many useful features... and your comment proved why: because upon seeing a problem, instead of accepting it, we try to solve it.

Sweet.

Please do submit a ticket or update to rails too see a feature like that be added to future releases.

@Ryan: Thanks for introducing another feature in such a concise manner.


7. Pascal May 21, 2008 at 12:36

Hi, I have this error on server startup:

/Library/Ruby/Gems/1.8/gems/activerecord-2.0.2/lib/active_record/base.rb:1532:in `method_missing': undefined method `partial_updates=' for ActiveRecord::Base:Class (NoMethodError)

I'm using Rails 2.0.2.

Any ideal?

Thx


8. Pascal May 21, 2008 at 13:02

@Pascal (me):

Forget it... I was running my project on Rails 2.0.2. I have to migrate my projet to 2.1 doh.


9. Alex May 21, 2008 at 15:17

Thanks for the rapid-fire onslaught of episodes lately. The recent Rails 2.1 episodes have been great. Keep on chuggin.


10. Peter Theill May 22, 2008 at 07:40

Since tracking of attribute changes have been introduced, I'm wondering if it's possible (through a configuration setting or similar) to implement a lost update check by extending the where clause, i.e. instead of Rails generating:

UPDATE users SET age = 30 WHERE id = ?

it should generate

UPDATE users SET age = 30 WHERE id = ? AND age = 29

if "age" attribute changed from 29 to being 30.


11. QuBiT May 22, 2008 at 09:43

@Peter Theill

go back and watch episode 59,
that's what you are looking for :)

http://railscasts.com/episodes/59


12. Ryan Bates May 22, 2008 at 10:50

@Peter, that's an interesting idea to only update if the existing record hasn't changed. It has some differences from optimistic locking in the fact that it only checks the columns it's updating. It doesn't consider changes to other columns a conflict.

This still suffers from the invalid record possibility problem. I would also hesitate adding it before fully exploring other potential problems. But it's worth investigating.


13. Virginian May 22, 2008 at 20:47

 Another great Railscasts, Thanks Ryan.

One question, when using partial updates rails is still validating all the attributes not just the ones changed. Is there a way to restrict it to only run validations on the changed attributes?


14. HappyCoder May 22, 2008 at 23:41

@Peter Theill
I don't understand. Why do you want that feature? The PK provides record's uniqueness. Isn't it enough? Besides, it has a performance issue. I mean, setting an index for every column in a table will not do any good.

[quote]
it should generate

UPDATE users SET age = 30 WHERE id = ? AND age = 29

if "age" attribute changed from 29 to being 30."
[/quote]


15. Ryan Bates May 22, 2008 at 23:43

@Virginian, not that I know of. Validations may not necessarily be tied to one attribute. It's possible a validation may rely on multiple attributes.

However, you can add this behavior manually when you specify the validations. To do this, add a condition to see if the attribute has changed before running the validation.


16. HappyCoder May 22, 2008 at 23:44

I was probably wrong about "performance issues" :-) I don't know how databases work in this situation. Does it search all records with such id (which is 1) and then finds from them just one with age=29?


17. Ryan Bates May 22, 2008 at 23:49

@HappyCoder, I haven't done any benchmarking so I can't say for sure if that would degrade performance. My guess is that it would be minimal.

As for your original question. The reason you may want to do this is to ensure the record hasn't been changed since you last fetched it. This way you don't mistakenly overwrite another change on the save.


18. Andrés May 30, 2008 at 16:56

Helo Ryan, can you tell me what is what you do to show the SQL statements executed by Rails at the bottom of the screen?

Thanks.


19. Virginian Jun 04, 2008 at 12:22

Hi Ryan-

I can do something like

  validates_presence_of :p1_new_first_name, :p1_new_last_name, :if => :p1_new_first_name_changed?

  validates_presence_of :p1_first_name, :p1_last_name, :if => :p1_first_name_changed?

And it almost works, but the flaw is obvious. If the attribute is left blank, it wont check be changed. I can run validations using this on almost anything except for presence_of is there any way around this?
Thanks for your help.


20. Pavel Jun 06, 2008 at 04:44

thank you very much! I have successfully used it. This is a very important thing for me :)


21. Jesse Jul 01, 2008 at 22:06

Ryan - Quick question, do you know why these don't work for virtual attributes that I've created using getter/setter methods? Thanks!


22. Matt Aug 08, 2008 at 14:13

Another thing to look out for with partial updates is that changes to a serialized attribute do not mark the attribute as changed, and as a result, will not get saved. So if you have a model called EmailQueue and a serialized attribute called "email" that stores a TMail object, and you try this:

c = EmailQueue.first
c.email.body = "new email body text"
c.save

You will find that the change was not saved. Perhaps there is an easy way to add a :before_save callback that marks the serialized attribute as dirty? But then I guess it's probably just as easy to turn off partial updates for the whole model.


23. Elaine Aug 21, 2008 at 08:24

I'd like to use this to replace the example in the #59 Optimistic Locking railscast, but I'm not having any luck in getting it to work. Of the fields in conflict, I'd like to show the field name that changed, what the value of the field was and what the user changed it to. Any help would be appreciated. Thanks.


24. Vinay Oct 16, 2008 at 03:16

@Ryan,
If you remember, there was an issue in episode 75 in which the Project.update_attributes was not calling the task_attributes= method (comments section Andrew). I dont know if it was ever resolved(I still have that problem and would love a solution) but i was just wondering if this was the reason. You mentioned that if records were not being saved properly for some reason, this could be it. Any thoughts?
Really appreciate your work Ryan. Thanks :)


25. replica iwc Jul 14, 2009 at 01:10

 Are you going to blog more on this? It looks like there’s more material here for more posts.


26. al-wlid Jul 22, 2009 at 17:47

Thank u so much for useful casts


27. Cheap Generic Viagra Oct 12, 2009 at 00:50

thank you for the information


28. ewtwt Nov 06, 2009 at 07:35

<p>Just wanted to say great job with the blog,

today is my first visit here and I’ve enjoyed

reading your posts so far<br /><a

href="http://www.mytobling.com/ugg-classic-tall-

boots-c-29.html">UGG Classic Tall Boots</a></p>


29. Anonymous Nov 20, 2009 at 15:21

Anyone know if this feature can be used for relational objects?

a has_many b

a.b_ids.changed?


30. ルイヴィトン Dec 07, 2009 at 07:08

The Malaysian 'Wan Shi Zan' janken is connected with this gosukumi. In this janken, pistol defeats everything except water, and bird loses to everything except water.


31. oak computer desk Jan 20, 2010 at 13:39

Just wanted to thank you for the download. I spent this past weekend playing around with Rails a bit and can really begin to see the power behind it. This is going to be fun.


32. afdsgfasd Jan 26, 2010 at 00:42

I feel [url=http://www.vivogame.com][b]wow gold[/b][/url] strongly that I can make it. 
我坚信我一定能成功。


33. dannysun Feb 23, 2010 at 06:13

This site is very good, thanks to the web master to give us this useful information


34. job search Mar 01, 2010 at 17:49

yeah, thanks for the tips.


35. Anaheim Mar 08, 2010 at 01:44

better change is appreciated.


36. nowgoogle.com adalah multiple search engine popular Mar 19, 2010 at 03:31

I am so lucky to meet this site, it is a very good site.


37. ghd Mar 25, 2010 at 00:53

3. My husband's brother-in-law,Joseph,an American real estate agent,<a href="http://www.vip-mbtstore.com/mbt-women-shoes/mbt-women-chapa-pumpkin.html">MBT Women Chapa - Pumpkin</a>came to China for a short visit to our city.<a href="http://www.vip-ghdhair.com/ghd-hair-straightener/limited-edition-kiss-styler.html">Limited Edition Kiss Styler</a>To show hospitality<a href="http://www.vip-mbtstore.com">mbt</a> at the welcoming dinner party,Mr.Sun,the host,entertained Joseph with Chinese wine,saying,<a href="http://www.vip-mbtstore.com/mbt-chapa/mbt-chapa-white.html">MBT Chapa - White</a>"According to our custom,a brother-in-law coming to his wife's native country for the first time must drink three cups of wine."


38. buy acai berry Apr 19, 2010 at 22:48

nice!


39. solar street lights Apr 21, 2010 at 22:05

very good solar street lights.


40. purchase propecia Apr 27, 2010 at 08:12

Comments do help sites flourish, especially w


41. christianlouboutinpayless May 07, 2010 at 01:16

thank you very much


42. MBT NFL JARDON AIR MAX GHD Jun 01, 2010 at 01:52

It's great to see an article like this. www.mbtselling.com www.jerseystown.com www.dunkjordan.com www.airmaxsupplier.com www.ghdbeautyhair.com


43. Never Give Up Dude Jun 17, 2010 at 05:23

nice info thank for shared


44. ebook pdf Jun 18, 2010 at 16:28

cool


45. cerita nakal Jun 18, 2010 at 16:29

nice info thank for shared


46. Facebook Games Jun 18, 2010 at 16:30

thanks


47. Point Blank Online Jun 18, 2010 at 16:30

awesome


48. Ninja Saga Amaterasu Jun 18, 2010 at 16:31

ninja


49. chunin exam Jun 18, 2010 at 16:31

chunin


50. bathroom vanities Jul 09, 2010 at 02:19

Okay, I will try this one. I hope this software can running faster than mine before. Thanks!


51. ed hardyswimwear Jul 20, 2010 at 00:45

http://www.pandora-jewelry-club.com/


52. cool electronic gadgets Jul 21, 2010 at 00:37

good post!


53. jordans shoes Jul 25, 2010 at 22:50

 I am so interested in it!


54. get diploma Jul 28, 2010 at 01:04

Very nice Site number one topic Thanks you..


55. home school Jul 28, 2010 at 21:56

Your posting is very good and theme base for which it is liking to every people. Thanks a lot!!!


56. Steam Showers Jul 29, 2010 at 21:51

What else can be worse than seeing closed ones doing such lies? Lol, but we learn from this. Thanks for sharing.


57. Start Sharing Not Selling Aug 02, 2010 at 04:38

Considerably, the article is really the sweetest on this noteworthy topic. I harmonise with your conclusions and will thirstily look forward to your approaching updates.


58. fetish escorts buffalo Aug 02, 2010 at 11:28

Amazing report you may have composed. I stubled onto the subject quite interesting generating a great entertaining learn.

Here are a few additional i always feel you will discover unique also


59. UGG Classic Argyle Knit Aug 03, 2010 at 23:04

  Your blog article is very intersting and fanstic,at the same time the blog theme is unique and perfect,great job.To your success.


60. Classic Crochet Uggs 5833 Aug 03, 2010 at 23:04

  This article is written in,I was looking for the information.Thank you and your share this articl at here


61. Teak Furniture: Teak Garden, Reclaimed Teak Furniture, Teak Patio from Indonesia Aug 05, 2010 at 11:30

good content


62. free directory list Aug 11, 2010 at 22:27

Thanks for blog!!!!Its very nice!!!


63. p90 workout Aug 12, 2010 at 09:19

I found your blog on Yahoo and I just wanted to say that I think your writing is simply stunning! Thanks again for providing this content for free.


64. Air Jordan Spizike Aug 14, 2010 at 02:17

Your blog article is very intersting and fanstic,at the same time the blog theme is unique and perfect,great job. nice info thank for shared


65. supra tk society Aug 18, 2010 at 18:49

good job,good article


66. supra tk society Aug 18, 2010 at 18:49

good job,good article


67. nike air max 2009 Aug 20, 2010 at 04:47

Good news,in here we will troduce


68. nike air max 2009 Aug 20, 2010 at 04:48

The 2010 FIFA World Cup is right around the corner


69. louis vuitton brea gm Aug 24, 2010 at 08:20

thank you very much


70. louis vuitton insolite wallet Aug 24, 2010 at 08:21

so good


71. airmaxplaza Aug 26, 2010 at 02:25

Discount air max classic bw : http://www.airmaxplaza.com/


72. LV SPEEDY 35 Aug 26, 2010 at 08:50

have a good time


73. jump higher Aug 26, 2010 at 13:20

It seems to me that model-level syntax to turn partial updates off or on conditionally would be smarter. For example:


74. louis vuitton shoes Aug 26, 2010 at 21:14

Thanks for sharing your article. I really enjoyed it. I put a link to my site to here so other people can read it. My readers have about the same interets


75. iPhone battery replacement Aug 26, 2010 at 22:21

Like prior comparable warm periods, those who concede them will argue that just because it was naturally warm before (or elsewhere) does not preclude man-made warming here and now.


76. Wholesale Electronics Aug 27, 2010 at 00:57

Discount Wholesale Electronics, Wholesale Cell Phones, Electronic Gadgets and More from the Best Dropship Wholesaler


77. mbt shoe uk Aug 30, 2010 at 01:34

http://www.curvedsoles.com I love your post, thank you for sharing.


78. snow boots Aug 31, 2010 at 00:21

 look at it as more of a performance improvement which can be applied if you have a model with BLOBs or index columns.


79. Cheap Supra Shoes Sep 01, 2010 at 00:21

Perfect


80. GHD Hair Straighteners Sep 01, 2010 at 00:22

Great article


81. GHD Australia Sep 01, 2010 at 00:23

Excellent article


82. louis vuitton sunglasses Sep 01, 2010 at 21:40

I think this is a great post. One thing that I find the most helpful is number five. Sometimes when I write, I just let the flow of the words and information come out so much that I loose the purpose. It’s only after editing when I realize what I’ve done. There’s defiantly a lot of great tips here I’m going to try to be more aware of.

Add your comment:

(SKIP THIS ONE)

(required)

(not shown)


(use pastie or gist for code)

sponsored by:
if you want to help:
required:
Get Quicktime Player
Give Back to Open Source