Назначение защищенного атрибута в Rails

У меня есть поле на моей модели пользователя, которое защищено, потому что оно определяет уровень допуска. Поэтому он должен быть защищен и не может быть назначен по массе. Таким образом, хотя атрибуты по умолчанию защищены в 3.2, на самом деле это поведение, которое я хочу.

Однако на одном методе контроллера я хочу разрешить менеджеру назначать это поле, например, при создании пользователя или обновлении пользователя.

Как разрешить назначение этого атрибута для определенных действий контроллера?

Например, у меня есть мой контроллер:

# app/controllers/admin/users_controller.rb

def create
    @user = User.new(params[:user])
# ...
end

Теперь, что я хотел бы сделать, это исключить clearance от params[:user], но, похоже, он отфильтровывается, вызывается и возникает исключение еще до того, как эта строка достигнута (я попытался debugger прямо перед этой строкой и даже закомментируйте ее, все равно возникло исключение).

Куда попадают защищенные атрибуты, если нет при вызове User#new ?

2 ответа

Решение

Способ Rails сделать это - назначить атрибуты без защиты или использовать роль администратора:

@user = User.new
@user.assign_attributes(params[:user], :without_protection => true)
@user.save

Тем не менее, я нашел это немного утомительным, поэтому я написал гем под названием sudo_attributes, который дает (на мой взгляд) лучший API:

@user = User.sudo_new(params[:user])
@user.save

Он имитирует все методы создания, создания и обновления Rails (new, build, create, create!, update_attributes и т. Д.).

В прошлом я предпочитал давать этой операции свой собственный метод, который устанавливает только это значение:

# app/controllers/admin/users_controller.rb

def full_clearance
  User.find(params[:id]).update_attribute(:clearance, 'full')
end

def restricted_clearance
  User.find(params[:id]).update_attribute(:clearance, 'restricted')
end

Теперь, посмотрев на путь Rails, о котором говорил Берлингтон, я бы предпочел использовать роли, чтобы дать конкретному действию доступ к атрибуту оформления:

# /app/models/user.rb

attr_accessible :attributes_accessible_by_default, ..., :clearance, :as => :manager

# app/controllers/admin/users_controller.rb

def create
    @user = User.new(params[:user].merge(:as => :manager)
# ...
end

В этом случае даже возможно предоставить пользователю доступ на основе атрибута роли:

# app/controllers/admin/users_controller.rb

def create
    @user = User.new(params[:user].merge(:as => current_user.role.to_sym)
# ...
end

но это может привести к возникновению ошибок снова.

Другие вопросы по тегам