根据建议,有足够的细节来保证将其作为答案分开。
我已经将问题追溯到一个模型,该模型定义method_missing
为其实现的一部分。我发现,如果method_missing
模型中有定义,则调用它而不是任何访问器。这会导致任何模型设置失败。
(在我的特定情况下,定义了 method_missing ,这就是导致我最初提到的堆栈溢出的原因)。
我可以通过在 Rails 3.2.14 中定义一个新的 rails 应用程序然后创建一个新模型来简洁地重现该问题:
class Item < ActiveRecord::Base
attr_accessible :name, :content
store :content
def method_missing(id, *args)
puts "method missing: #{id}"
end
end
以及相关的迁移
class CreateItems < ActiveRecord::Migration
def change
create_table :items do |t|
t.string :name
t.text :content
t.timestamps
end
end
end
如果我运行 rails 控制台,我可以练习模型:
$ rails console
Loading development environment (Rails 3.2.14)
2.0.0p247 :001 > x = Item.new(name: 'foo')
=> #<Item id: nil, name: "foo", content: {}, created_at: nil, updated_at: nil>
2.0.0p247 :002 >
如果我在 Rails 4.0.0 中构建完全相同的东西,我会得到不同的输出:
$ rails console
Loading development environment (Rails 4.0.0)
2.0.0p247 :001 > x = Item.new(name: 'foo')
method missing: name=
=> #<Item id: nil, name: nil, content: {}, created_at: nil, updated_at: nil>
2.0.0p247 :002 >
您会注意到,在 Rails 3.2.14 中,该name
属性被设置foo
为意图。然而,在 Rails 4.0.0 中,看到它method_missing
被调用并且属性没有被设置。
我正在阅读对 ActiveRecord 的更改,但我找不到任何表明method_missing
在 Rails 4 之前使用的模型在 Rails 4 中不再适用的任何内容。
任何使代码示例能够在 Rails 4 中运行的指针都将帮助我解决我的模型遇到的问题。
更新
通过手动调用向上method_missing
链,我可以让上面的例子工作:
def method_missing(id, *args)
super
if respond_to? id
send(id,*args)
else
puts "method missing: #{id}"
end
end
需要这样做对我来说感觉不对,因为不清楚为什么这种行为在 Rails 3 和 4 之间发生了变化。我觉得我错过了其他东西......