Skip to content

Instantly share code, notes, and snippets.

@cokara
Created October 23, 2013 01:50
Show Gist options
  • Save cokara/7111247 to your computer and use it in GitHub Desktop.
Save cokara/7111247 to your computer and use it in GitHub Desktop.

Assuming you have a Postgres table called maps, created by the following migration:

create_table :maps do |t|
  t.string :name
  t.string :grid, array: true, length: 3, default: Array.new(3,nil)
 end

And you have the following ActiveRecord class with a function that modifies the grid

class Map < ActiveRecord
  def update_grid(index, value)
    grid[index] = value
    g.save
  end
end

This is what happens in the console:

m = Map.create
m.update_grid(0, "Foo")
m.reload.grid # => [nil,nil,nil]

So whats going on here? It turns out that ActiveRecord treats the array the same even though its contents have changed and hence ignores the changed values inside it. This happens when using in place or destructive changes like <<, pop or push. To persist such a change in AR one needs to use the <attribute>_will_change! method on an AR object which makes the attribute 'dirty'.

class Map < ActiveRecord
  def update_grid(index, value)
    grid_will_change!
    grid[index] = value
    g.save
  end
end

and from the console you get this:

m = Map.create
m.update_grid(0, "Foo")
m.reload.grid # => ["Foo",nil,nil]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment