Skip to content
This repository

String attribute isn't marked as dirty, when it changes with `<<` #6954

Closed
Mik-die opened this Issue · 5 comments

3 participants

Mikhail Dieterle Carlos Antonio da Silva Dmitry Vorotilin
Mikhail Dieterle

Rails 3.2.6

1.9.3-p194 :001 > cc = Campaign.first
  Campaign Load (6.1ms)  SELECT "campaigns".* FROM "campaigns" LIMIT 1
 => #<Campaign ...> 
1.9.3-p194 :002 > cc.tags
 => " health style" 
1.9.3-p194 :003 > cc.tags << " another"
 => " health style another" 
1.9.3-p194 :004 > cc.tags_changed?
 => false 
1.9.3-p194 :005 > cc.tags += " another"
 => " health style another another" 
1.9.3-p194 :006 > cc.tags_changed?
 => true 
Carlos Antonio da Silva

Exactly, this is how it works. Rails knows you're changing something when you set the attribute value, there's no way for Rails to know that you're doing a change on the same string. This means that, when using things like << or replace on a string, for example, you have to tell Rails that this attribute has changed using *_will_change!, otherwise dirty tracking won't work.

Using your example:

> cc.tags << " another"
 => " health style another" 
> cc.tags_changed?
 => false 
> cc.tags_will_change!
 => nil 
> cc.tags_changed?
 => true

Thanks!

Dmitry Vorotilin
route commented

@carlosantoniodasilva You've explained current realization, but probably is there a chance to change this behavior, wdyt?

Carlos Antonio da Silva

There's no way to change the behavior, unless we wrap all core ruby objects. Rails has no way to know you're changing a string in place, unless we create a RailsString thing that would know how to handle it (or monkey patch). Rails knows you're writing an attribute, because it creates the writers, but in place change is not possible. Any approach I can think of, is automatically followed by an "out of question". It'd be good to make it work, for sure, but I highly believe there's no way other than `_will_change! methods, which are actually quite clear when we understand the reasonings. Thanks!

Dmitry Vorotilin
route commented

Thanks for explanation!

Carlos Antonio da Silva

No problem :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Something went wrong with that request. Please try again.