我有一个 Rails 3.0.9 应用程序,一旦部署,就会遇到一堆 ActiveModel::MissingAttributeErrors ,这些错误会突然出现,导致 500 秒。错误的发生相当随机,有时会加载页面,有时则不会,但这些属性都是数据库中现有的属性,应该可以找到。
奇怪的是,过了一会儿,错误就消失了。突然间,他们不再制造问题了。
我已经搜索过此问题的解决方案,但此错误大多发生在有人完成
Model.all(:select => 'column_x,column_y')
并调用 column_z
或使用 cache_money 时。我没有做这两件事。
有人可以帮忙吗?
您可能有一个不返回所有列的查询(即使用
:select
),然后返回cache_money;或其他一些 ActiveRecord 插件使用 after_initialize
回调,每当创建新的 ActiveRecord 对象时(即从数据库获取时)都会执行该回调。
在该初始化回调中,某些内容尝试访问或使用未包含在
:select
中的属性。您希望该属性返回 nil,但实际上会抛出 ActiveRecord::MissingAttributeError。
您可以像文章建议的那样挽救 ActiveRecord::MissingAttributeError,或者修补插件以在尝试访问或修改属性之前使用
has_attribute?(:attribute_name)
。
如果您仅在更新数据库后直接遇到此问题,而没有任何部署或服务器重新启动,那么对我有用的方法可能对您也有用:
运行
heroku restart
,它应该被修复。在测功机重新启动之前,旧数据有时仍缓存在服务器上,因此再次启动将清除所有数据并防止其导致此类错误。希望这有帮助。
我遇到了这个问题。确保您的
select:
包含视图中引用的所有字段,包括任何关系 ID 以及方法中调用的任何属性。
当您的观点和关系很复杂时,缺失的属性可能很难识别。调试此问题的最简单方法是删除
select
子句中的 where
部分,然后查看查询/作用域/方法是否正确运行。如果是这样,则将所有属性添加到 select
并一次删除一个不需要的属性,直到找到有问题的属性。
我发现了一个有趣的做法,导致了同样的错误。为了重用代码,我们使用执行分组以在图形视图中使用的演示者类对演示者类进行子类化。
为了简化,它是这样的:
class PostPresenter
def query
Post.where(...stuff....).includes(:wombat)
end
end
聚合器执行了类似以下操作来构建每天的帖子表:
class AggregatePostPresenter < PostPresenter
def group_query
query.select('count(*) as cnt, date(created_at)').group('date(created_at)')
end
end
调用“group_query”会导致 ActiveModel::MissingAttributeError,因为我认为“包含”Wombat 的尝试失败了,因为“wombat_id”不在“select”中包含的属性中。
但这可能不是您的答案,因为无论是否启用缓存,它都会发生。
当我尝试进行 Ajax(实际上是 angularjs)调用来填充就地编辑选择字段时,类似的问题让我很烦恼。
我只想要一个 id 和 name 属性 to_json 并不断收到 MissingAttributeError。
意识到我自己被模型中的 as_json 方法困扰,该方法用于主索引并显示模型上的调用。基本上是 as_json 没有看到它期望的属性。
@foo=Foo.select("id,name")
respond_to do |format|
format.json { render :json => @foo.to_json }
end
给出了错误,但是
respond_to do |format|
format.json { render :json => { :foo=>@foo.as_json(:only=>[:id,:name]) } }
end
似乎正在发挥作用。我自己也差点怀疑它,但我在
找到了一个很好的解释。我通过将
.to_json
添加到控制器渲染的末尾来修复此问题。
(不是特定于问题描述,而是特定于错误标题)
这可能对仍然看到缺少属性错误的人有帮助。
当我没有从数据库加载属性时,我遇到了这个错误。
user = User.where(some_criteria).only(:id, :first_name).first
user.last_name # throws missing attribute error because it wasn't loaded in `only` method
您可能只从某些存储中加载选择属性,只需确保您正在获取所需的字段即可。
您需要添加行
rescue ActiveRecord::MissingAttributeError
在模型的 after_initialize() 方法中