今天从3.2.7升级到Rails 3.2.9,似乎已从ActiveRecord中删除了“to_i”方法。
这是设计的吗?或者这是一个错误?我在改变说明中找不到任何提及。这会影响很多代码。
谢谢!
答案 0 :(得分:4)
#to_i
方法从未存在过,但将对象分配给值的方式为changed in Rails 3.2.8。
鉴于以下内容:
class Lecture < ActiveRecord::Base
has_one :professor
end
以前你可以指派教授参加这样的讲座:
@lecture.professor = Professor.find_by_id(1)
或者像这样:
@lecture.professor_id = Professor.find_by_id(1)
在第一种情况下,一切都很简单,因为professor
关联需要一个教授对象。在第二种情况下,虽然ActiveRecord执行了一些魔法来强制教授的id,因为professor_id
需要一个整数。
在Rails 3.2.8及更高版本中,魔法不再适用。它在某种程度上很好,因为它暗示你可能做错了什么。例如,如果数据库中没有professor_id
列,但只有professor
期望一个整数,则此类分配将不再有效。
答案 1 :(得分:2)
Rails 3.2.9中的“to_i”方法有一个变化,但它处理列而不是表。 见here。
因此,在您的代码中,如果您传递的是整个对象而不是列值,那么它之前就会无声地失败。但现在它实际上会在对象上调用“to_i”方法并引发异常。
答案 2 :(得分:2)
我遇到了同样的错误。并不是说ActiveRecord缺少#to_i而是其他东西,在我的情况下涉及factory_girl gem。
factory_girl (4.1.0)
factory_girl_rails (4.1.0)
以下是一个与众不同的案例:
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
然后在控制台中:
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>
但是,如果我使用以下步骤执行相同的步骤:
rails _3.2.11_ new rails3211
然后在控制台中我看到:
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>
注意Rails 3.2.11的nil user_id
答案 3 :(得分:0)
我不相信to_i
方法在AR对象上有自己的事件。您是否可以对该方法的早期使用有所了解,现在失败了?
答案 4 :(得分:0)
要跟进Luca,我正在使用Rails 3.2.11并且我不确定我是否有这样的代码,但我确实发现它不再有效:
@lecture.update_attribute(:professor_id, Professor.find_by_id(1))
答案 5 :(得分:0)
当我将rails版本3.2.3升级到rails 3.2.11时,我也遇到了同样的问题。
以下是一些代码片段,其中存在哪些确切问题
在轨道3.2.3中
医生=医生。第一
病人= Patient.new
patient.doctor_id = doctor(右侧对象分配有效)
patient.save! (有效)
在轨道3.2.11中
医生=医生。第一
病人= Patient.new
patient.doctor_id = doctor(右侧对象分配无效)
patient.save! (无效)
NoMethodError:未定义的方法'to_i'错误我们得到了这种分配。
结论我们只使用_ID = INTEGER而不仅仅是对象分配 More details