Upgraded to Rails 3.2.9 today from 3.2.7 and it appears that the method "to_i" has been removed from ActiveRecord.
Is this by design? Or is it a bug? I cannot find any mention of it in the change notes. This is going to impact a lot of code.
thanks!
The #to_i
method never existed, however the way assigning objects to values has changed in Rails 3.2.8.
Given the following:
class Lecture < ActiveRecord::Base
has_one :professor
end
Previously you could assign a professor to a lecture like this:
@lecture.professor = Professor.find_by_id(1)
Or like this:
@lecture.professor_id = Professor.find_by_id(1)
In the first case everything is simple as the professor
association expects a professor object. In the second case though ActiveRecord performed some magic to coerce the id from the professor, as professor_id
expects a integer instead.
In Rails 3.2.8 and above that magic no longer works. It is nice in a way as it is a hint you are probably doing something wrong. For example, if there isn't a professor_id
column in the database, but just professor
which expects an integer, assigning like this will no longer work.
It looks like this will be reverted to the previous behaviour in Rails 3.2.11.
There has been one change with regards to "to_i" method in Rails 3.2.9, but that deals with the columns and not with the tables. See here.
So in your code, if you were passing entire object instead of column value, it was failing silently before. But now it will actually call the "to_i" method on the object and raise exception.
I ran into the same error. It's not that ActiveRecord lacks #to_i but something else, which in my case involves the factory_girl gem.
factory_girl (4.1.0)
factory_girl_rails (4.1.0)
Here's an isolated case of the difference:
rails _3.1.0_ new rails31
cd rails31
bundle install
rails g scaffold note title:string contents:text
rails g scaffold user name:string
rails g migration add_user_id_to_notes user_id:integer
rake db:migrate
Then in the console:
require 'factory_girl'
FactoryGirl.define { factory :note }
Factory(:note, :user_id => User.first, :title => 'foo')
User Load (0.1ms) SELECT "users".* FROM "users" LIMIT 1
SQL (0.5ms) INSERT INTO "notes" ("contents", "created_at", "title", "updated_at", "user_id") VALUES (?, ?, ?, ?, ?) [["contents", nil], ["created_at", Sun, 13 Jan 2013 21:29:36 UTC +00:00], ["title", "foo"], ["updated_at", Sun, 13 Jan 2013 21:29:36 UTC +00:00], ["user_id", 1]]
=> #<Note id: 3, title: "foo", contents: nil, created_at: "2013-01-13 21:29:36", updated_at: "2013-01-13 21:29:36", user_id: 1>
However, if I do the same sequence of steps with:
rails _3.2.11_ new rails3211
Then in the console I see:
1.9.2-p290 :001 > require 'factory_girl'
=> true
1.9.2-p290 :002 > FactoryGirl.define { factory :note }
=> []
1.9.2-p290 :003 > Factory(:note, :user_id => User.first, :title => 'foo')
User Load (0.1ms) SELECT "users".* FROM "users" LIMIT 1
(0.0ms) begin transaction
SQL (24.5ms) INSERT INTO "notes" ("contents", "created_at", "title", "updated_at", "user_id") VALUES (?, ?, ?, ?, ?) [["contents", nil], ["created_at", Sun, 13 Jan 2013 21:33:03 UTC +00:00], ["title", "foo"], ["updated_at", Sun, 13 Jan 2013 21:33:03 UTC +00:00], ["user_id", nil]]
(2.4ms) commit transaction
=> #<Note id: 1, title: "foo", contents: nil, created_at: "2013-01-13 21:33:03", updated_at: "2013-01-13 21:33:03", user_id: nil>
Note the nil user_id for Rails 3.2.11
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With