1

I have model User

class User < ActiveRecord::Base
    has_and_belongs_to_many :roles

    attr_accessible :login, :email, :password, :password_confirmation ...
    attr_accessible :role_ids, :active, :as => :super_admin

    validates :email, :presence => true,
                      :format => {:with => /\A[\w+\-.]+@[a-z\d\-.]+\.[a-z]+\z/i},
                      :uniqueness => {:case_sensitive => false},
                      :restricted_email_domain => true
    ...
end

and two separate user controllers for front-end and back-end. First one is very trivial and works well, second one is below

class Admin::UsersController < Admin::BaseController
    def create
        @user = User.new
        @user.assign_attributes(params[:user], :as => :super_admin)
        if @user.save
        ...
    end
    def update
        @user = User.find(params[:id])
        if @user.update_attributes(params[:user], :as => :super_admin)
        ...
    end
end

I'm using custom validator that checks whether user's email domain restricted or not

class RestrictedEmailDomainValidator < ActiveModel::EachValidator
    def validate_each(record, attr_name, value)
        if !value.include?("@") # this value is nil if I add ":as => :super_admin"
            record.errors.add(attr_name, :invalid, options.merge(:value => value))
        else
            domain = value.split("@")[1]
            record.errors.add(attr_name, :restricted_email_domain, options.merge(:value => value)) if ::RestrictedEmailDomain.where(:domain => domain).exists?
        end  
    end
end
module ActiveModel::Validations::HelperMethods
    def validates_restricted_email_domain(*attr_names)
        validates_with RestrictedEmailDomainValidator, _merge_attributes(attr_names)
    end
end

Update action works well but create action gives You have a nil object when you didn't expect it! error in config/initializers/restricted_email_domain_validator.rb:3:in 'validate_each'. Without :as => :super_admin everything is ok, but of course role_ids and active attributes are not assigned.

I can assign values manually, but I think it is not a perfect solution.

lucapette
  • 20,564
  • 6
  • 65
  • 59
Babur Ussenakunov
  • 1,995
  • 2
  • 16
  • 16

1 Answers1

2

I may be wrong, as I don't have a way to check it now, but I think that when you write

attr_accessible :role_ids, :active, :as => :super_admin
  • only these two attributes are accessible to you when you modify them as super_admin. So @user.assign_attributes(params[:user], :as => :super_admin) - only sets these two fields, leaving the rest in default state.

Did you try something like

attr_accessible :login, :email, :password, :password_confirmation ...
attr_accessible :login, :email, :password, :password_confirmation ..., :role_ids, :active, :as => :super_admin
Nox
  • 395
  • 3
  • 22
  • Is there a way to define default attr_accessible attributes, then add to it based on the role you assign attributes as? Thus avoiding repeating :login, :email, ... – Kevin Lawrence Jan 04 '13 at 23:17
  • 2
    You can define attr_accessible [list_of_common_attributes], as: [:default, :superadmin], attr_accessible [list_of_admin_attrs], as: :superadmin – Nox Mar 19 '13 at 07:26
  • 1
    @poc Nox has an extra comma in there. Should read: `attr_accessible list_of_common_attributes, as: [:default, :superadmin] attr_accessible list_of_admin_attrs, as: :superadmin` – varatis Jul 26 '13 at 01:23