클래스 기본값을 설정하고 서브 클래스에서 재정의 허용을위한 Ruby on Rails 패턴

StackOverflow https://stackoverflow.com/questions/1072767

문제

기본적으로 나는 간단한 레일 확장을 구현하여 컨트롤러의 방법의 심각성을 정의하여 적절하게 사용을 제한 할 수 있도록하고 싶습니다. 예를 들어, 나는 기본 편안한 동작을 추상 슈퍼 클래스에서 그렇게 정의합니다.

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

그런 다음 비 임금 컨트롤러 호출로 내려갑니다.

edit_methods :sort

특정 컨트롤러의 정렬 메소드를 편집 레벨 방법으로 추가합니다.

그런 다음 Prever_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

위의 세 가지 방법은 내가 시도한 것을 보여주기 위해 의도적으로 다릅니다. 세 번째는 작동하지만 어떤 컨트롤러를 테스트하든 동일한 결과를 반환합니다. 아마도 클래스 변수가 응용 프로그램 컨트롤러에 저장되므로 전역으로 변경되기 때문일 수 있습니다.

모든 도움은 대단히 감사하겠습니다.

도움이 되었습니까?

해결책

문제는 클래스 변수가 상속되었지만 동일한 인스턴스를 가리킨다는 것입니다. Array. 하나를 업데이트하면 상속 된 모든 클래스에서도 업데이트됩니다. Array.

ActiveSupport a 해결책 이 문제를 확장 하여이 문제에 Class 정의 할 몇 가지 방법이있는 클래스 상속 가능한 클래스 속성. 그들은 내부에서 철도에있는 모든 곳에서 사용됩니다. An example:

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]

다른 팁

나는 그것을 같은 플러그인으로 바꿨습니다.

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에서 효력을 발휘하려는 Super_Controller에서 트릭을 수행합니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top