我使用Rails 5.0.5和Devise 4.3.0进行身份验证。此应用程序已运行数月,直到我添加了'类型' =>'字符串'属性到我的用户模型并尝试创建新用户。提交表单会给我500个内部服务器错误。在此示例中,User.type =' hunter'。
NameError - wrong constant name hunter:
activesupport (5.0.5) lib/active_support/inflector/methods.rb:268:in `const_get'
activesupport (5.0.5) lib/active_support/inflector/methods.rb:268:in `block in constantize'
activesupport (5.0.5) lib/active_support/inflector/methods.rb:266:in `each'
activesupport (5.0.5) lib/active_support/inflector/methods.rb:266:in `inject'
activesupport (5.0.5) lib/active_support/inflector/methods.rb:266:in `constantize'
activesupport (5.0.5) lib/active_support/dependencies.rb:583:in `get'
activesupport (5.0.5) lib/active_support/dependencies.rb:614:in `constantize'
activerecord (5.0.5) lib/active_record/inheritance.rb:177:in `find_sti_class'
activerecord (5.0.5) lib/active_record/inheritance.rb:209:in `subclass_from_attributes'
activerecord (5.0.5) lib/active_record/inheritance.rb:55:in `new'
devise (4.3.0) lib/devise/models/registerable.rb:20:in `new_with_session'
app/models/user.rb:58:in `new_with_session'
user.rb:
def self.new_with_session(params, session)
if session['devise.user_attributes']
new(session['devise.user_attributes']) do |user|
user.attributes = params
user.valid?
end
else
super
end
end
Rails认为这个属性值是ClassName吗?似乎无法解决这个问题。非常感谢任何帮助。
答案 0 :(得分:1)
默认情况下,ActiveRecord使用type
列进行单表继承(STI),type
值应命名为类。大概你没有hunter
课,所以你会从ActiveRecord的内心深处感到困惑NameError
。
来自fine manual:
<强> inheritance_column()强>
定义表列的名称,该列将在单表继承情况下存储类名。默认继承列名称为
type
,这意味着它是Active Record中的保留字。为了能够将单表继承与其他列名一起使用,或者将您自己模型中的列type
用于其他内容,您可以设置inheritance_column
:self.inheritance_column = 'zoink'
将type
列重命名为其他内容,或者告诉ActiveRecord为STI使用其他列名称:
class User < ApplicationRecord
self.inheritance_column = 'there_is_no_sti_here' # Or whatever you're not using for a column name.
end
使用self.inheritance_column = nil
也可以。
如果您经常这样做,那么您可以通过添加关注点来声明它:
module STISuppression
extend ActiveSupport::Concern
included do
self.inheritance_column = nil
end
end
然后说出类似的话:
class SomeModel < ApplicationRecord
include STISuppression
end
同样的效果,但它清楚地说明了你的目标。