1

基本的に、単純なRails拡張機能を実装して、コントローラーのメソッドの重大度を定義し、メソッドの使用を適切に制限できるようにします。たとえば、抽象スーパークラスでデフォルトのRESTfulアクションをそのように定義します。

view_methods :index, :show
edit_methods :new, :create, :edit, :update
destroy_methods :destroy

次に、非抽象コントローラー呼び出しでダウンします。

edit_methods :sort

その特定のコントローラーに編集レベルのメソッドとしてsortメソッドを追加します。

次に、before_filterを使用して、現在実行されているアクションのレベルを確認し、現在のユーザーが実行できないとロジックが判断した場合は、それを中止できます。

問題は、この種の構造を設定する方法を理解するのに苦労していることです。私はこれまでにこのようなことを試しました:

class ApplicationController

  @@view_methods = Array.new
  @@edit_methods = Array.new
  @@destroy_methods = Array.new

  def self.view_methods(*view_methods)
    class_variable_set(:@@view_methods, class_variable_get(:@@view_methods) << view_methods.to_a)
  end

  def self.edit_methods(*edit_methods)
    class_variable_set(:@@edit_methods, self.class_variable_get(:@@edit_methods) << edit_methods.to_a)
  end

  def self.destroy_methods(*destroy_methods)
    @@destroy_methods << destroy_methods.to_a
  end

  def self.testing
    return @@edit_methods
  end


  view_methods :index, :show
  edit_methods :new, :create, :edit, :update
  destroy_methods :destroy

end

上記の3つの方法は、私が試したことを示すために、意図的に異なります。3つ目は機能しますが、どのコントローラーをテストしても同じ結果が返されます。おそらく、クラス変数がアプリケーションコントローラに格納されているため、グローバルに変更されます。

どんな助けでも大歓迎です。

4

2 に答える 2

3

問題は、クラス変数が継承されているが、の同じインスタンスを指していることですArray。更新すると、を継承したすべてのクラスでも更新されますArray

ActiveSupport継承可能なクラス属性を定義するためにいくつかのメソッドでクラスを拡張することにより、この問題の解決策を提供します。それらはRailsの内部の至る所で使用されています。例:Class

class ApplicationController
  class_inheritable_array :view_method_list
  self.view_method_list = []

  def self.view_methods(*view_methods)
    self.view_method_list = view_methods  # view_methods are added
  end

  view_methods :index, :show
end

これで、でデフォルト値を設定しApplicationController、後でそれらをオーバーライドできます。

class MyController < ApplicationController
  view_method :my_method
end

ApplicationController.view_method_list #=> [:index, :show]
MyController.view_method_list #=> [:index, :show, :my_method]

コントローラのインスタンスメソッドview_method_listとしてを使用することもできます(例)。MyController.new.view_method_list

あなたの例では、リストからメソッドを削除する方法を定義していませんが、アイデアは次のようなことをすることです(必要な場合):

# given the code above...
class MyController
  self.view_method_list.delete :show
end
MyController.view_method_list #=> [:index, :my_method]
于 2009-07-02T07:38:51.863 に答える
0

私はそれを次のようなプラグインに変えました:

module ThreatLevel

  def self.included(base)
    base.send :extend, ClassMethods
  end

  module ClassMethods
    def roger_that!
      class_inheritable_array :view_method_list, :edit_method_list, :destroy_method_list

      self.view_method_list = Array.new
      self.edit_method_list = Array.new
      self.destroy_method_list = Array.new

      def self.view_methods(*view_methods)
        self.view_method_list = view_methods
      end

      def self.edit_methods(*edit_methods)
        self.edit_method_list = edit_methods
      end

      def self.destroy_methods(*destroy_methods)
        self.destroy_method_list = destroy_methods
      end

      view_methods :index, :show
      edit_methods :new, :create, :edit, :update
      destroy_methods :destroy
    end
  end
end

ActionController::Base.send :include, ThreatLevel

roger_thatを呼び出します!有効にしたいsuper_controllerでトリックを実行します。

于 2009-07-03T01:45:21.347 に答える