Domanda

Sto aggiornando il mio Rails plugin per essere un motore che funziona con l'ultima versione 3.0RC1 e sto avendo un po 'di difficoltà a capire il migliore (e più corretto) modo per estendere ActionController. Ho visto questo post da DHH e questa domanda qui su SO, ma la mia domanda è di più su come chiamare correttamente il codice all'interno del ActionController.

Per esempio, ho bisogno di chiamare il seguente all'interno del controller del mio motore:

class ApplicationController < ActionController::Base
  helper :all

  before_filter :require_one_user
  after_filter :store_location

  private
    def require_one_user
      # Code goes here
    end

    def store_location
      # Code goes here
    end
end

So come includere correttamente le mie due funzioni private, ma non riesco a trovare un modo per farlo chiamare correttamente helper, before_filter e after_filter.

Io apprezzo molto alcuni link o un modo per fare questo lavoro. Ho provato nominare il mio controller qualcosa di diverso da ApplicationController e avere la vera ApplicationController estenderla, ma che non sembra funzionare. Sono davvero per qualsiasi soluzione che rende la vita del utente del motore più semplice possibile. Idealmente, essi non avrebbero dovuto estendere la mia classe, ma avevano avere tutte le funzionalità integrate nel proprio ApplicationController.

È stato utile?

Soluzione

Si può anche voler guardare negli inizializzatori all'interno della vostra sottoclasse del motore, in modo da non è necessario includere vista aiutanti all'interno della vostra classe controller. E questo vi darà di controllare l'ordine di caricamento di questi moduli.

Ecco quello che ho utilizzato:


module MyEngine  
  class Engine < Rails::Engine  
    initializer 'my_engine.helper' do |app|  
      ActionView::Base.send :include, MyEngineHelper  
    end  

    initializer 'my_engine.controller' do |app|  
      ActiveSupport.on_load(:action_controller) do  
         include MyEngineActionControllerExtension  
      end
    end
  end
end

Inoltre, un'altra opzione per l'estensione regolatore azione sta utilizzando un modulo mixin. Questo vi permetterà di utilizzare il before_filter, after_filter, etc ..


module MyEngineActionControllerExtension
  def self.included(base)
    base.send(:include, InstanceMethods) 
    base.before_filter :my_method_1
    base.after_filter :my_method_2
  end

  module InstanceMethods
   #...........
  end
end

Un altra cosa ... se si crea il default rotaie directory al livello più alto del vostro gioiello, non si deve preoccuparsi di richiedere gli aiutanti o controller. Il tuo sottoclasse motore ha accesso ad essi. Quindi aggiungo il mio controller delle applicazioni e le estensioni applicazione di supporto qui:

/myengine/app/helpers/myengine_application_helper_extension.rb
/myengine/app/controllers/my_engine_action_controller_extension.rb

Mi piace questa messa a punto perché sembra simile al application_controller e application_helper nella vostra applicazione Rails. Ancora una volta, questa è la preferenza solo personale, ma cercare di mantenere tutto ciò che è direttamente rotaie correlati, come controllori, aiutanti e modelli all'interno / my_engine / app e tutto ciò che è legato al plugin in all'interno generale / my_engine / lib

Guarda questo tutorial da José Valim per più informazioni inizializzatori: https://gist.github.com/e139fa787aa882c0aa9c (ENGINE_NAME è deprecato ora, ma la maggior parte di questo documento sembra up-to-date)

Altri suggerimenti

Così, ho finalmente capito la soluzione e spero che aiuta a qualcun altro.

È necessario creare un file nella directory lib, perché in realtà si sta andando ad estendere la classe. Ho fatto myplugin/lib/extensions/action_controller_base.rb.

Poi, all'interno del file myplugin/lib/myplugin.rb, procedere come segue:

require 'extensions/action_controller_base.rb'

All'interno della myplugin/lib/extensions/action_controller_base.rb mettere il seguente:

require 'action_controller'  # Make sure ActionController::Base is defined

ActionController::Base.class_eval {
  private
    def my_method_1
      # Code Goes Here
    end

    def my_method_2
      # Code Goes Here
    end
}

ActionController::Base.instance_eval {
  helper_method :my_method_1, :my_method_2

  before_filter :my_method_1
  after_filter :my_method_2
}

Se avete bisogno di avere vista aiutanti, li creare nella directory myplugin/lib/helpers (o nulla all'interno dei lib, il nome "aiutanti" non importa) anche e aggiungere il seguente al fondo della myplugin/lib/extensions/action_controller_base.rb:

require 'helpers/helper_file_1'
require 'helpers/helper_file_2'

ActionView::Base.send :include, MyHelper1
ActionView::Base.send :include, MyHelper2
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top