7

今天从 3.2.7 升级到 Rails 3.2.9,似乎方法“to_i”已从 ActiveRecord 中删除。

这是设计使然吗?或者它是一个错误?我在更改说明中找不到任何提及。这将影响很多代码。

谢谢!

4

6 回答 6

4

#to_i方法从未存在,但是在 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需要一个整数,则这样的分配将不再有效。

看起来这将恢复到 Rails 3.2.11 中的先前行为

于 2013-01-07T17:37:00.977 回答
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

于 2013-01-13T21:38:01.367 回答
2

Rails 3.2.9 中的“to_i”方法有一个变化,但它处理的是列而不是表。见这里

因此,在您的代码中,如果您传递的是整个对象而不是列值,那么它之前会默默地失败。但现在它实际上会调用对象上的“to_i”方法并引发异常。

于 2012-12-04T23:10:08.497 回答
0

我不相信该to_i方法在他们自己的 AR 对象上可用。您能否更具体地了解该方法的早期用途,但现在失败了?

于 2012-12-01T20:23:48.210 回答
0

是的,当我将 rails 3.2.3 版升级到 rails 3.2.11 时,我也遇到了同样的问题。

这是一些代码片段有什么确切的问题

在 Rails 3.2.3中,
医生 = Doctor.first
patient = Patient.new
patient.doctor_id =doctor (右侧对象分配有效)
Patient.save!(有效)

在 rails 3.2.11
中医生 = Doctor.first
患者 = Patient.new 患者.doctor_id
= 医生(右侧对象分配无效)
Patient.save!(无效)
NoMethodError: undefined method 'to_i' error 我们得到了这种分配。

结论是我们只使用 _ID = INTEGER 而不是像对象分配一样。
更多细节

于 2013-01-21T16:18:51.853 回答
0

为了跟进 Luca,我使用的是 Rails 3.2.11,我不确定我是否有这样的代码,但我确实发现它不再起作用:

@lecture.update_attribute(:professor_id, Professor.find_by_id(1))
于 2013-01-09T11:54:03.687 回答