NameError - 创建用户时设置错误的常量名称(Devise,Rails)

时间:2018-04-01 00:41:11

标签: ruby-on-rails devise rails-activerecord

我使用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吗?似乎无法解决这个问题。非常感谢任何帮助。

1 个答案:

答案 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

同样的效果,但它清楚地说明了你的目标。