2015-01-22 3 views
0

У меня есть несколько моделей с атрибутами, которые обычные пользователи не могут изменить, но администраторы должны. Например (хотя это не мой проблемный домен), обычные пользователи не должны изменять Postuser_id, но администраторы должны иметь возможность сделать это.Разрешение дополнительных параметров для учетных записей администратора

Обработка этого на уровне представления достаточно проста - я могу показывать или не показывать поля в зависимости от того, является ли пользователь администратором, но я не уверен, как обращаться с ним в сильной обработке параметров контроллера. Единственное решение, которое я могу придумать (и решения offered previously) является повторяться, кое-что вы пытаетесь сделать не в Rails:

def post_params 
    if admin? 
    params.require(:post).permit(:title, :text, :date, :user_id) 
    else 
    params.require(:post).permit(:title, :text, :date) 
end 
end 

Есть ли лучший способ справиться с этим?

ответ

0

Вам не нужно искать два разных списка параметров, чтобы предотвратить появление плохих пользователей. Скорее вы должны рассмотреть возможность использования cancan Gem.

Поддерживайте использование единого списка параметров равномерно (независимо от роли пользователя).

При том, что ограничение/защитить ваши действия (на основе роли пользователя), попробуйте использовать cancan gem.

Определите свои индивидуальные разрешения ролей в ability.rb файле.

Образец файла способность будет выглядеть следующим образом:

#ability.rb 

class Ability 
    include CanCan::Ability 

    def initialize(user) 
    user ||= User.new 

    if user.is?(:Administrator) # Access for Admin user 
     can :access, :all 
    elsif user.is?(:"Finance Manager") #Access for Finance Manager 
     can :access, [:subjects, :researchsubjects, :visits, :sessions] 
    elsif user.is?(:"Research Director") # Access for Research Director 
    else 
     #do something 
    end 
    end 
end 

Пожалуйста, проверьте, cancan gem для получения дополнительной информации.

+0

Cancan - это крутой камень, который ограничивает доступ к действиям контроллера и действиям модели. Можете ли вы дать код, как использовать его с сильными параметрами, чтобы ограничить ввод пользователя? – BroiSatse

1

Я не вижу ничего плохого в вашей текущей реализации. При этом, если вы хотите повторно использовать эти разрешения атрибутов в другом контроллере (например, Api :: PostsConrtoller), одним из способов DRY это будет извлечение кода в его собственный класс. Это подход Райан Бэйтс, используемый в Railscast about Strong Parameters (примечание: требуется учетная запись Pro).

# app/models/permitted_params.rb 

class PermittedParams < Struct.new(:params, :user) 
    def post 
    if user && user.admin? 
     params.require(:post).permit(:title, :text, :date, :user_id) 
    else 
     params.require(:post).permit(:title, :text, :date) 
    end 
    end 
end 

Вы можете создать экземпляр этого класса внутри ApplicationController

# app/controllers/application_controller.rb 

def permitted_params 
    @permitted_params ||= PermittedParams.new(params, current_user) 
end 

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

# app/controllers/posts_controller.rb 

def update 
    @post = Post.find(params[:id]) 
    if @post.update_attributes(permitted_params.post) 
    ... 
    else 
    ... 
    end 
end 

Что действительно приятно об этом решении является то, что вы можете также использовать его для DRY-ваши взгляды, слегка изменив PermittedParams класс.

# app/models/permitted_params.rb 

class PermittedParams < Struct.new(:params, :user) 
    def post 
    params.require(:post).permit(*post_attributes) 
    end 

    def post_attributes 
    if user && user.admin? 
     [:title, :text, :date, :user_id] 
    else 
     [:title, :text, :date] 
    end 
    end 
end 

и подвергая метод permitted_params как помощник вида.

# app/controllers/application_controller.rb 

def permitted_params 
    @permitted_params ||= PermittedParams.new(params, current_user) 
end 
helper_method :permitted_params 

Наконец, используйте его в своем представлении, чтобы показать/скрыть поля формы.

# app/views/posts/edit.html.erb 

<% if permitted_params.post_attributes.include? :user_id %> 
# show the user_id field 
<% end %> 
0

Я не был доволен ни одним из предыдущих ответов.Я действительно хотел это сделать:

params.require(:post).permit(:title, :text, :date, user_id: admin?) 

Поэтому я решил сделать это возможным. Сначала я попытался пропатчить ядро ​​Rails, но они не были заинтересованы в принятии патча:

Этот API является деликатным, есть несколько направлений, в которых она могла бы эволюционировать, и он может легко получить из рук, непоследовательными , или создать ожидания для расширения расширений ... Мы предпочитаем к тому, чтобы сохранить это как есть.

В общем, мы предпочитаем варианты использования, которые не поддерживаются API, которые могут быть решены при регулярном программировании. В этом случае было бы

pkeys = [:title, :body] 
pkeys << :author_id if admin? 
params.require(:post).permit(*pkeys) 

или что-то в этой строке (вы уже знали, что это возможно, конечно, но только для иллюстрации точки с примером).

Итак, я turned it into a gem instead, и я буду использовать его до тех пор, пока я хочу его сохранить. Жаль, что эта функция не будет частью каждого будущего приложения Rails, которое я пишу, но, по крайней мере, я смогу получить его из своего Gemfile.

gem 'rails_conditional_params' 
Смежные вопросы