Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Closed
mikdiet opened this issue Jul 4, 2012 · 5 comments
Closed

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

mikdiet opened this issue Jul 4, 2012 · 5 comments

Comments

@mikdiet
Copy link
Contributor

mikdiet commented Jul 4, 2012

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 
@carlosantoniodasilva
Copy link
Member

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!

@route
Copy link
Contributor

route commented Jul 5, 2012

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

@carlosantoniodasilva
Copy link
Member

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!

@route
Copy link
Contributor

route commented Jul 6, 2012

Thanks for explanation!

@carlosantoniodasilva
Copy link
Member

No problem :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants