복붙노트

[RUBY-ON-RAILS] 주요 응용 프로그램의 레일 3 엔진의 컨트롤러를 확장

RUBY-ON-RAILS

주요 응용 프로그램의 레일 3 엔진의 컨트롤러를 확장

나는 내 응용 프로그램의 보석 같은 레일 엔진을 사용하고 있습니다. 엔진은 방법의 번호가 PostsController을 가지고 있는데 내 주요 응용 프로그램, 예를 들어,에 컨트롤러 로직을 확장하고자하는 몇 가지 방법을 추가 할 수 있습니다. 난 그냥 주요 애플 리케이션에가 PostsController를 만들 경우, 엔진의 컨트롤러가로드되지 않습니다.

변질 ActiveSupport :: 종속성 # require_or_load에 따라 기능을 확장 질문 레일 엔진에서 제안 된 해결책이 있습니다

그것은이 작업을 수행 할 수있는 유일한 / 올바른 방법이 있나요? 예는, 어디한다면 나는 코드의 조각을 넣어?

EDIT1

이 레일 2.x에서 안드리가 제시 한 코드입니다

module ActiveSupport::Dependencies
  alias_method :require_or_load_without_multiple, :require_or_load
  def require_or_load(file_name, const_path = nil)
    if file_name.starts_with?(RAILS_ROOT + '/app')
      relative_name = file_name.gsub(RAILS_ROOT, '')
      @engine_paths ||= Rails::Initializer.new(Rails.configuration).plugin_loader.engines.collect {|plugin| plugin.directory }
      @engine_paths.each do |path|
        engine_file = File.join(path, relative_name)
        require_or_load_without_multiple(engine_file, const_path) if File.file?(engine_file)
      end
    end
    require_or_load_without_multiple(file_name, const_path)
  end
end

해결법

  1. ==============================

    1.당신의 응용 프로그램에서 엔진의 컨트롤러 클래스에서 상속 (새로운 아이 컨트롤러에 당신의 경로를 가리 킵니다)하지 왜? 당신이 내장 뻗어있는 것을 고안 컨트롤러 방법을 개념적으로 유사한 소리.

    당신의 응용 프로그램에서 엔진의 컨트롤러 클래스에서 상속 (새로운 아이 컨트롤러에 당신의 경로를 가리 킵니다)하지 왜? 당신이 내장 뻗어있는 것을 고안 컨트롤러 방법을 개념적으로 유사한 소리.

  2. ==============================

    2.디자인함으로써, 레일 :: 엔진의 클래스는 엔진에 범위 수로되어있다. 그렇지 않은 그런 식으로 실수 주요 응용 프로그램 또는 다른 엔진에 의해로드 된 모든 이상 코드를 쾅쾅에 의해 이상한 버그를 소개합니다. 더 - 보드가 건너-정말 나쁜 해결 방법입니다 Monkeypatching ActiveSupport :: 종속성 엔진을 혼합합니다.

    디자인함으로써, 레일 :: 엔진의 클래스는 엔진에 범위 수로되어있다. 그렇지 않은 그런 식으로 실수 주요 응용 프로그램 또는 다른 엔진에 의해로드 된 모든 이상 코드를 쾅쾅에 의해 이상한 버그를 소개합니다. 더 - 보드가 건너-정말 나쁜 해결 방법입니다 Monkeypatching ActiveSupport :: 종속성 엔진을 혼합합니다.

    그냥 대신, 레일 :: Railtie를 사용합니다. 그들은 모두 동일한 기능을 가지고 있지만, 엔진과 동일한 방식으로 범위가되지 않습니다. 당신은 (엔진 포함) 전체 레일 응용 프로그램 스택에 액세스 할 수 있습니다. 그것은 더 수술 방법입니다.

    module MyModule
    
      module SomeModelExtensions
        # Called when this module is included on the given class.
        def self.included(base)
          base.send(:include, InstanceMethods)
          base.extend(ClassMethods)
        end
    
        module ClassMethods
          def some_new_class_method
            # do stuff...
          end
        end
    
        module InstanceMethods
          def some_new_instance_method
            # do stuff...
          end
        end
    
      end
    
      module SomeControllerExtensions
        def self.included(base)
          base.send(:include, InstanceMethods)
          base.alias_method_chain :new, :my_module
        end
    
        module InstanceMethods
          # override the 'new' method
          def new_with_my_module
            # do stuff
          end
        end
      end
    
      class Railtie < ::Rails::Railtie
    
        # The block you pass to this method will run for every request in
        # development mode, but only once in production.
        config.to_prepare do
          SomeModel.send(:include, MyModule::SomeModelExtensions)
          SomeController.send(:include, MyModule::SomeControllerExtensions)
        end
    
      end
    
    end
    

    파일 레이아웃까지로, railties 정확히 엔진처럼 보인다.

    또한 읽기 : Railties와 레일 3 확장

    https://github.com/jamezilla/bcms_pubcookie : 당신은 아직도 혼동하는 경우 그리고, 전체 구현이이 자식 프로젝트를 살펴

  3. ==============================

    3.여기에 필요 후 나는 application.rb 내 레일 3 응용 프로그램에 넣어 무엇인가 '레일 / 모든'(그것을 넣어 나쁜 곳이 있다면 알려주세요)

    여기에 필요 후 나는 application.rb 내 레일 3 응용 프로그램에 넣어 무엇인가 '레일 / 모든'(그것을 넣어 나쁜 곳이 있다면 알려주세요)

    require 'active_support/dependencies'
    module ActiveSupport::Dependencies
      alias_method :require_or_load_without_multiple, :require_or_load
      def require_or_load(file_name, const_path = nil)
        if file_name.starts_with?(Rails.root.to_s + '/app')
          relative_name = file_name.gsub(Rails.root.to_s, '')
          #@engine_paths ||= Rails::Application.railties.engines.collect{|engine| engine.config.root.to_s }
          #EDIT: above line gives deprecation notice in Rails 3 (although it works in Rails 2), causing error in test env.  Change to:
          @engine_paths ||= YourAppName::Application.railties.engines.collect{|engine| engine.config.root.to_s }
          @engine_paths.each do |path|
            engine_file = File.join(path, relative_name)
            require_or_load_without_multiple(engine_file, const_path) if File.file?(engine_file)
          end
        end
        require_or_load_without_multiple(file_name, const_path)
      end
    end
    

    이 작동하지 않았다 동안 가축 용

    TypeError in PostsController#index
    
    superclass mismatch for class PostsController
    

    하지만 클래스가 PostsController <와 ApplicationController해야 잘못 입력 클래스 정의 클래스가 PostsController

    모든 엔진 컨트롤러 등이 작업을 수행하지 않으려면, 당신은 주요 응용 프로그램의 정의 전에 엔진의 컨트롤러를로드 할 수 있습니다

    require PostsEngine::Engine.config.root + 'app' + 'controllers' + 'posts_controller'
    
    class PostsController < ApplicationController
      # extended methods
    end
    
  4. ==============================

    4.나는 위의 안드리 안드레이의 코드를 기반으로 보석을 만들었습니다. 대신에 그 코드를 주위에 복사하는 바로 mixable_engines 보석이 필요합니다. 만 지금 레일 3와 함께 작동합니다.

    나는 위의 안드리 안드레이의 코드를 기반으로 보석을 만들었습니다. 대신에 그 코드를 주위에 복사하는 바로 mixable_engines 보석이 필요합니다. 만 지금 레일 3와 함께 작동합니다.

    https://github.com/asee/mixable_engines

    https://rubygems.org/gems/mixable_engines

    @Andrei 및 @Artrius : 나는 당신이 당신의 진짜 이름이나 다른 신용을 원하는 경우 알려주세요, 라이센스 파일에서 당신을 적립했습니다.

  5. ==============================

    5.이 기능을 확장 레일 엔진에서 제안로드 순서를 변경하기 위해 적극적인 지원을 패치하지 않으려면, 당신은 인증을위한 랙 미들웨어를 사용할 수있다. 인증이 모든 컨트롤러 액션의 일부로 수행되는 경우,이 방법은 당신에게 코드와 많은 시간을 절약 할 수 있습니다.

    이 기능을 확장 레일 엔진에서 제안로드 순서를 변경하기 위해 적극적인 지원을 패치하지 않으려면, 당신은 인증을위한 랙 미들웨어를 사용할 수있다. 인증이 모든 컨트롤러 액션의 일부로 수행되는 경우,이 방법은 당신에게 코드와 많은 시간을 절약 할 수 있습니다.

  6. ==============================

    6.당신은 엔진이 생성 될 때 컨트롤러에 코드를 주입하는 루비의 send () 메소드를 사용할 수 있습니다 ...

    당신은 엔진이 생성 될 때 컨트롤러에 코드를 주입하는 루비의 send () 메소드를 사용할 수 있습니다 ...

    # lib/cool_engine/engine.rb
    
    module CoolEngine
      class Engine < ::Rails::Engine
    
        isolate_namespace CoolEngine
    
        initializer "cool_engine.load_helpers" do |app|
          # You can inject magic into all your controllers...
          ActionController::Base.send :include, CoolEngine::ActionControllerExtensions
          ActionController::Base.send :include, CoolEngine::FooBar
    
          # ...or add special sauce to models...
          ActiveRecord::Base.send :include, CoolEngine::ActiveRecordExtensions
          ActiveRecord::Base.send :include, CoolEngine::MoreStuff
    
          # ...even provide a base set of helpers
          ApplicationHelper.send :include, CoolEngine::Helpers
        end
      end
    end
    

    이 방법은 당신의 주요 응용 프로그램 내에서 컨트롤러 상속을 재정의 할 필요에서 당신을 여분.

  7. ==============================

    7.require_dependency 및 config.reload_plugins와 함께 @cowboycoded 방법 2 레일 3.2.2 / 루비 1.9에 저했다.

    require_dependency 및 config.reload_plugins와 함께 @cowboycoded 방법 2 레일 3.2.2 / 루비 1.9에 저했다.

    여기 코드는 다음과 같습니다 https://stackoverflow.com/a/9790497/22237

  8. from https://stackoverflow.com/questions/5045068/extending-controllers-of-a-rails-3-engine-in-the-main-app by cc-by-sa and MIT license