2016-04-18 4 views
0

Я использую pundit для авторизации в приложении rails. Для некоторых моделей я хочу авторизацию на уровне атрибута. Например, нормальному пользователю разрешено изменять свой номер телефона, но он не может установить свой статус «администратор».Атрибуция уровня атрибута в представлениях с помощью pundit

Как рекомендуется в the Pundit docs, я использую для этого permitted_attributes.

Теперь я хочу получить доступ к этим атрибутам, чтобы определить, какие поля показывать или разрешать в форме. Есть ли (элегантный) способ сделать это без существенного повторения разрешенных полей?

ответ

2

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

class ApplicationPolicy 
    #... 

    def permits_attributes?(*attrs) 
    attrs.keep_if({|a| permits_attribute?(a) }).any? 
    end 

    def permits_attribute?(attr) 
    permitted_attributes.include?(attr) 
    end 

    # ... 
end 

Затем можно создать пользовательскую форму строитель (или модуль, который расширяет форму строитель) :

class MyFormBuilder < ActionView::Helpers::FormBuilder 
    def can_fill_in?(attr) 
    yeild if @template.policy(object).permits_attribute?(attr) 
    end 
end 

<%= form_for(@project, builder: MyFormBuilder) do |f| %> 
    <%= f.can_fill_in?(:title) do %> 
    <%= f.label :title %> 
    <%= f.text_field :title %> 
    <% end %> 
<% end %> 

Вы также можете настроить рельсы использовать пользовательские Ф.О. гт строитель по умолчанию:

ActionView::Base.default_form_builder = MyFormBuilder 

См:

+0

Спасибо, я добавил методы в политике приложения и создали пользовательские формы строитель, но я не могу получить доступ политика от помощника. Я получаю «неопределенный метод« политика »для # " – bmesuere

+0

Вы попробовали позвонить @ template.policy? Я понял, что сделал опечатку и написал ее с пространством. @template - это ссылка на контекст представления, который должен иметь политику, а не класс построителя форм. – max

+0

Да, я попробовал как @ template.policy, так и view_context.policy. В самом представлении я могу без проблем получить доступ к политике. – bmesuere