Rails 3 CanCan HTML Helpers - PullRequest
       12

Rails 3 CanCan HTML Helpers

0 голосов
/ 17 ноября 2011

Я использую стандартные помощники HTML

<%= form_for @person do |f| %>
 <%= f.label :first_name %>:
 <%= f.text_field :first_name %><br />
<%end%>

Но допустим, я хочу деактивировать текстовое поле, если имя первого пользователя не редактируется текущим пользователем. Так что CanCan говорит, что я могу сделать это

<%= f.text_field :name if can? :update, @person, :first_name %>

Это хорошо, но я хотел бы абстрагировать это как-то так:

<%= f.conditional_text_field :first_name %>

В этом примере мой пользовательский помощник HTML знает, что я говорю о @person, потому что он в форме помощника через f.object. Мне это нравится, потому что переработанная обработка нередактируемых атрибутов может контролироваться централизованно. Я мог бы отображать отключенное поле ввода или отображать текст. Если ничего другого, у меня есть удобный крючок для обновления авторизации, если CanCan изменится, будет заменен чем-то в будущем, или я хочу подключиться к какой-нибудь сумасшедшей вещи рабочего процесса.

  1. Это похоже на хорошую идею?

  2. Уже есть драгоценный камень для этого?


Обновление

В настоящее время я смотрю на добавление помощника следующим образом:

def can_text_field(f, field, *args)
  field = field.to_sym
  if can? :update, f.object, field
    return f.text_field field.to_sym *args
  else
    if can? :read, f.object, field
      return f.object.send(field)
    else
      return "Not Authorized"
    end
  end
end

1 Ответ

0 голосов
/ 18 ноября 2011

Я пошел с обновлением FormHelper

class ActionView::Helpers::FormBuilder

  alias :original_text_field :text_field
  def text_field(method, options = {})
    if @@current_ability.cannot? :update, self.object, method.to_sym
      options[:disabled]="disabled"
    end
    self.original_text_field(method, options)
  end

  alias :origianl_collection_select :collection_select
  def collection_select(method, collection, id_method, display_method,
                        options={}, html_options={})
    if @@current_ability.cannot? :update, self.object, method.to_sym
      html_options[:disabled]="disabled"
    end
    self.original_collection_select(method, collection, id_method,
                                    display_method, options, html_options)
  end

  def self.set_current_ability(current_ability)
    @@current_ability = current_ability
  end

end

Мне пришлось добавить контроллер before_filter, чтобы загрузить FormBuilder с current_ability

class ApplicationController < ActionController::Base
  before_filter :set_current_ability

  private

  def set_current_ability
    ActionView::Helpers::FormBuilder.set_current_ability( current_ability )
  end
end
...