"add_column :posts, :foo; Post.first.foo = 'blah'" fails silently #6679

Closed
jdelStrother opened this Issue Jun 8, 2012 · 11 comments

Comments

Projects
None yet
6 participants
Contributor

jdelStrother commented Jun 8, 2012

Hi,
If you have a migration like this :

   add_column :posts, :foo, :text
   Post.find_each do |p|
      p.foo = 'bar'
      p.save!
    end

the posts are successfully saved, but the new value for 'foo' isn't persisted to the database - you just end up with a table full of nil values for 'foo'.

Post.reset_column_information fixes this. I was surprised, however, by the following -

  • "post.foo = 'blah'" works fine, it just doesn't persist to the database. Given the column information appears to be out of date, wouldn't you expect NoMethodError on trying to assign to :foo ?
  • Surely ActiveRecord could implicitly call reset_column_information after each schema definition statement (eg add_column) ? I'm struggling to think of cases where this might cause a perceivable performance hit.
Contributor

waseem commented Jun 10, 2012

I was unable to reproduce this. The test that I wrote is at https://gist.github.com/2906016

Contributor

al2o3cr commented Jun 10, 2012

Have definitely encountered this on Postgres (but only in production mode, argh).

@waseem: I suspect there may be some caching happening on Person.all in your test.

Contributor

jdelStrother commented Jun 10, 2012

We had it on mysql in 3.2.5. Let me see if I can come up with a test case...

Contributor

jdelStrother commented Jun 10, 2012

Hmm. I don't know if it's been fixed in Rails 4, but this fails in 3.2.5 for me : https://gist.github.com/2907225

Contributor

jdelStrother commented Jun 10, 2012

...yeah, I can't seem to reproduce in rails 4, but I've been digging through the source & can't quite figure out what's different.

Have you tried to git bisect ?

Contributor

jdelStrother commented Jun 11, 2012

@waseem took me a while to spot, but this doesn't invoke the block :

person_klass.all do |person|
  ...
end

I suspect you meant

person_klass.find_each do |person|
  ...
end

?


I'm now able to reproduce it on 4.0 with this test : https://gist.github.com/2909025.

Contributor

waseem commented Jun 11, 2012

@jdelStrother Your test cases confirm that this is indeed an issue. I also looked at some test cases which call reset_column_information after add_column. I'm not sure if it's intended behavior though. Maybe you should submit a pull request addressing this issue. We can then gather core's attention then.

Contributor

jdelStrother commented Jun 11, 2012

Owner

senny commented Apr 2, 2013

#6702 was closed because using Models in migrations is not advised at all. If you absolutely have to, there is the reset_column_information workaround.

/cc @rafaelfranca

senny closed this Apr 2, 2013

Owner

rafaelfranca commented Apr 2, 2013

Confirm

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