read_inheritable_attribute 在生产中意外修改
这种情况发生在 Rails 3.0.7 和 3.0.9、WEBrick 和 Apache 中。
我有一个模块 Reportable
,它有一个编写 inheritable_attribute
的方法:
module Reportable
module ClassMethods
def add_report(report_name)
instance_eval do
write_inheritable_hash(:reportable_report_names,
{report_name => {:dates => true, :details => 'something'})
end
end
end
end
def self.included(base)
base.extend(ClassMethods)
end
end
Reportable
加载到 config/initializers
中,并且一个类使用它:
class User < ActiveRecord::Base
include Reportable
add_report :report1
add_report :report2
end
在生产模式下,服务器启动后第一次加载页面时,属性加载正确:
User.read_inheritable_attribute(:reportable_report_names)
# => {:report1 => {:dates => true, :details => 'something'},
:report2 => {:dates => true, :details => 'something'}}
但在第二次页面加载时:
User.read_inheritable_attribute(:reportable_report_names)
# => {:report1 => {:dates => true},
:report2 => {:dates => true}}
它在开发中按预期工作,在生产模式下在控制台中按预期工作。该问题仅出现在生产模式下 Web 服务器上的 POST 请求中。什么给?
This is happening in Rails 3.0.7 and 3.0.9, WEBrick and Apache.
I have a module Reportable
that has a method that writes an inheritable_attribute
:
module Reportable
module ClassMethods
def add_report(report_name)
instance_eval do
write_inheritable_hash(:reportable_report_names,
{report_name => {:dates => true, :details => 'something'})
end
end
end
end
def self.included(base)
base.extend(ClassMethods)
end
end
Reportable
is loaded in config/initializers
and a class uses it:
class User < ActiveRecord::Base
include Reportable
add_report :report1
add_report :report2
end
In production mode, the first time I load a page after the server starts, the attribute loads correctly:
User.read_inheritable_attribute(:reportable_report_names)
# => {:report1 => {:dates => true, :details => 'something'},
:report2 => {:dates => true, :details => 'something'}}
But on the second page load:
User.read_inheritable_attribute(:reportable_report_names)
# => {:report1 => {:dates => true},
:report2 => {:dates => true}}
It works as expected in development, and in the console in production mode. The problem only appears in a POST request on the web server in production mode. What gives?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
刚刚尝试过,在所有环境下都可以正常工作。还有其他细节吗?
否则:
既然您正在处理模型本身,为什么要使用
instance_eval
?你应该使用 splat 来传递参数
这将导致:
在模型中:
Just tried, it works in all environments without problem. Any other details?
Otherwise:
why do you use
instance_eval
since you're working on the model itself?you should use a splat to pass arguments
This would lead to:
And in model:
经过一番头痛之后,原因是
read_inheritable_attribute
返回的是引用而不是值。引发错误的操作重定向到另一个操作,这是问题的真正原因。该模块还有另一个方法:
另一个操作执行了以下操作:
因为
available_reports
返回了一个引用,所以dup
没有执行任何操作,并且keep_if
删除了我的宝贵资源来自类变量的值。解决方法是:
感谢那些花时间检查这个问题的人,尽管其中没有足够的信息来正确回答。
After a lot of headaches, the cause was that
read_inheritable_attribute
returned a reference rather than value.The action throwing the error redirected to another action, which was the true cause of the problem. The module had another method:
And the other action did this:
Because
available_reports
returned a reference, thedup
did nothing and thekeep_if
deleted my precious values from the class variable.The fix was:
Thanks to those who took the time to check this question out even though there wasn't enough information in it to be answered properly.