【问题标题】:Rails 3 CanCan HTML HelpersRails 3 CanCan HTML 助手
【发布时间】:2011-11-17 01:07:17
【问题描述】:

我正在使用标准导轨 HTML 帮助程序

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

但是假设如果当前用户无法编辑 first_name,我想停用 text_field。所以 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

【问题讨论】:

    标签: ruby-on-rails authorization html-helper cancan


    【解决方案1】:

    我更新了 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 以使用 current_ability 加载 FormBuilder

    class ApplicationController < ActionController::Base
      before_filter :set_current_ability
    
      private
    
      def set_current_ability
        ActionView::Helpers::FormBuilder.set_current_ability( current_ability )
      end
    end
    

    【讨论】:

      猜你喜欢
      • 2010-12-16
      • 2011-08-04
      • 2011-04-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-05-21
      • 1970-01-01
      相关资源
      最近更新 更多