Rails and devise: model attribute not being persis

2019-08-26 10:10发布

问题:

I edited devise's RegistrationsController::create method to modify slightly the behaviour. What I'm trying to do is that if there are no admin users in the database, the one that first signs up is going to be assigned the admin role, else it will be a regular user.

However, the role, though assigned correctly to the object (tested), it's not being persisted to the database.

Model:

class User < ActiveRecord::Base
  devise :database_authenticatable, :registerable,
         :recoverable, :rememberable, :trackable, :validatable

  attr_accessor :role

  Roles = [ :admin, :default ]

  def is? requested_role
    self.role == requested_role.to_s
  end

  def self.admin_role
    return Roles[0]
  end

  def self.default_role
    return Roles[1]
  end
end

Modified devise method:

def create
  build_resource(sign_up_params)

  admin_user = User.find_by_role(User.admin_role)
  if admin_user.nil?
    resource.role = User.admin_role
  else
    resource.role = User.default_role
  end

  # here puts resource.role shows what's expected is indeed being assigned to the object

  if resource.save
    ...
  end
end

Why isn't the role being stored in the database? Why is it NULL?

回答1:

You don't need the attr_accessor for :role if you have this defined as a column on your table. ActiveRecord gives you the database backed accessors just by having the relevant column defined in the relevant table.

Your attr_accessor will be overriding these and preventing them from persisting your changes to the database.