This project is archived and is in readonly mode.

#608 ✓invalid
quake wang

Dirty checking is broken for string join

Reported by quake wang | July 13th, 2008 @ 04:14 AM | in 2.x

Rails 2.1:

create_table :topics do |t|

t.string :title


class Topic < ActiveRecord::Base


in console:

>> t = Topic.find(1)

>> t.title = t.title << "new"

>> t.changed?

=> false

Comments and changes to this ticket

  • Jason Dew

    Jason Dew July 14th, 2008 @ 05:30 PM

    Don't see an easy fix, but a workaround is s/<</+=/

  • Jason Dew
  • Tom Ward

    Tom Ward July 25th, 2008 @ 12:26 PM

    This ticket is invalid. Dirty checking will only currently work if you replace an attribute with a new value, not edit it in place.

    Instead you should do:

    t = Topic.find(1)
    t.title = t.title << "new"
    # => true
  • Clemens Kofler

    Clemens Kofler July 25th, 2008 @ 02:22 PM

    • Tag set to activerecord

    I agree with Tom. It is known that all changes that don't go through standard assignment with = will not mark the attribute as changed.

  • quake wang

    quake wang July 26th, 2008 @ 02:26 AM

    I know will_change can resolve this issue as a temp solution, however, how to explain the inconsistent of string / numeric field?

    create_table :topics do |t|

    t.string :title

    t.integer :score


    t = Topic.find(1)

    t.title =


    1. => false

    t.score = t.score.*(33)


    1. => true
  • Tom Ward

    Tom Ward July 26th, 2008 @ 10:30 AM

    What does do?

    If you set the title to the same value it was before, changed? will return false.

    If you set it to a new value, it should return true.

  • Pratik

    Pratik July 26th, 2008 @ 03:19 PM

    • State changed from “new” to “invalid”

    Patch please.

  • Clemens Kofler

    Clemens Kofler July 26th, 2008 @ 03:29 PM

    I've tested this and I can confirm it.

    A little something to think about before someone actually spends time on creating a patch that isn't really necessary:

    With t.title << "new", I would actually think that the title changes. t.title = t.title << "new" looks intriguing to me because it looks like it does the actual assignment twice. IMO you shouldn't "reassign" the variable when using the << operator.

    What would make sense, though, is having something like t.title = t.title + "new" or its short form, t.title += "new". Both of them actually work perfectly fine and t.title_changed? returns true.

    The important question to ask is whether one should use something misleading like t.title = t.title << "new" when there's two valid ways around that even look more logical. One is, as I said, t.title += "new" and the other would be to use t.title_will_change! t.title << "new".

  • Zach Holman

    Zach Holman July 31st, 2008 @ 09:00 PM

    I can confirm this as well.

    There's some discussion on whether something is "changed" if the contents are changed. To me that seems like a valid case. I was working on a serialized array to a model, and if I do something like:


    my_model.serialized_array << 'new pushed element'

    my_model.changed # intuitively this should return ["serialized_array"]


    I feel that this is a common scenario where a serialized array needs modification, and the very idea of something being modified is, well, a change.

Create your profile

Help contribute to this project by taking a few moments to create your personal profile. Create your profile »

<h2 style="font-size: 14px">Tickets have moved to Github</h2>

The new ticket tracker is available at <a href=""></a>

Referenced by