CanCanCan Role must exist + User already exists 错误

CanCanCan Role must exist + User already exists error

我曾经设计过处理用户 signup/signin。我现在正在尝试使用 CanCan 来实现管理员、版主和普通用户。 我希望默认注册为 'registered' 或普通用户。我按照他们的指导做了这个。 在 seeds.rb:

['admin', 'moderator', 'registered'].each do |role|
    Role.find_or_create_by({name: role})
end

在role.rb中:

class Role < ApplicationRecord
    has_many :users
end

在user.rb中:

class User < ApplicationRecord
  # Include default devise modules. Others available are:
  # :confirmable, :lockable, :timeoutable and :omniauthable
  devise :database_authenticatable, :registerable,
         :recoverable, :rememberable, :trackable, :validatable

  has_many :todos
  belongs_to :role
  before_create :set_default_role

  private
  def set_default_role
    self.role ||= Role.find_by_name('registered')
  end
end

但是,每当我点击注册时。我在页面上收到一条错误消息 'Role must exist',这就是我在控制台中收到的消息:

Started POST "/users" for 127.0.0.1 at 2018-01-25 10:38:27 +0500
Processing by Devise::RegistrationsController#create as HTML
  Parameters: {"utf8"=>"✓", "authenticity_token"=>"yBNCK6YInQTx3YsYFSDTToPMpS4NCUz0bTLxGxyeFq2zHWTJWwkkHqcblbsN+7CJEQEsfjtC2VlbuPvVyomv5Q==", "user"=>{"email"=>"umar@gmail.com", "password"=>"[FILTERED]", "password_confirmation"=>"[FILTERED]"}, "commit"=>"Sign up"}
   (0.1ms)  begin transaction
  User Exists (0.1ms)  SELECT  1 AS one FROM "users" WHERE "users"."email" = ? LIMIT ?  [["email", "umar@gmail.com"], ["LIMIT", 1]]
   (0.1ms)  rollback transaction
  Rendering devise/registrations/new.html.erb within layouts/application
  Rendered devise/shared/_links.html.erb (0.6ms)
  Rendered devise/registrations/new.html.erb within layouts/application (2.7ms)
Completed 200 OK in 149ms (Views: 13.6ms | ActiveRecord: 0.3ms)

而且我还没有接触过 ability.rb。好像哪里不对?

而不是在 creation 阶段设置角色,您应该在验证之前设置它,如下所示:

before_validation :set_default_role, on: [:create, :update]

如果您查看以调用顺序相同的顺序显示所有回调列表的文档,您会注意到 validation 回调在 create 回调之前调用。

现在,Activerecord 发现用户在 validation 阶段没有附加 role,它会抛出与您看到的相同的错误。

有关回调的更多详细信息,请参阅此文档:http://guides.rubyonrails.org/active_record_callbacks.html#creating-an-object