NameError - 创建用户时常量名称错误(设计,Rails)
NameError - wrong constant name when creating user (Devise, Rails)
我正在使用 Rails 5.0.5 和 Devise 4.3.0 进行身份验证。这个应用程序已经 运行 顺利运行了几个月,直到我向我的用户模型添加了一个 'type'=>'string' 属性并尝试创建一个新用户。提交表单给我一个 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??似乎无法弄清楚这一点。非常感谢任何帮助。
ActiveRecord 默认将 type
列用于单一 Table 继承 (STI),并且 type
值应命名为 class。大概你没有 hunter
class 所以你从 ActiveRecord 的内部深处得到一个令人困惑的 NameError
。
来自fine manual:
inheritance_column()
Defines the name of the table column which will store the class name on single-table inheritance situations.
The default inheritance column name is type
, which means it's a reserved word inside Active Record. To be able to use single-table inheritance with another column name, or to use the column type
in your own model for something else, you can set 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
同样的效果,但它让你清楚地知道你在做什么。
我正在使用 Rails 5.0.5 和 Devise 4.3.0 进行身份验证。这个应用程序已经 运行 顺利运行了几个月,直到我向我的用户模型添加了一个 'type'=>'string' 属性并尝试创建一个新用户。提交表单给我一个 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??似乎无法弄清楚这一点。非常感谢任何帮助。
ActiveRecord 默认将 type
列用于单一 Table 继承 (STI),并且 type
值应命名为 class。大概你没有 hunter
class 所以你从 ActiveRecord 的内部深处得到一个令人困惑的 NameError
。
来自fine manual:
inheritance_column()
Defines the name of the table column which will store the class name on single-table inheritance situations.The default inheritance column name is
type
, which means it's a reserved word inside Active Record. To be able to use single-table inheritance with another column name, or to use the columntype
in your own model for something else, you can setinheritance_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
同样的效果,但它让你清楚地知道你在做什么。