在Rails 3.2.9中删除了ActiveRecord to_i方法

时间:2012-11-12 18:02:23

标签: ruby-on-rails-3.2

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

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

谢谢!

6 个答案:

答案 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期望一个整数,则此类分配将不再有效。

看起来这将是reverted to the previous behaviour in Rails 3.2.11

答案 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