2016-06-29 4 views
1

カスタムサインアップページでdeviseをカスタマイズしていましたが、他の操作と共にアカウントを作成した後にsign_inにユーザを招待しました。私が行ったリソースを作成した後モジュールをインポートせずにsign_inリソースを作成する

sign_in resource if resource.active_for_authentication? 

サインインします。私のコントローラは ApplicationControllerに を継承し、私はどのようにレールが

sign_in 

方法について知っていたこの

include Devise::Controllers::SignInOut 

のような任意のモジュールが含まれていない

答えて

1

基本的な答え - モジュールの工夫::コントローラ::ヘルパー(発見したDevise :: Controllers :: SignInOutを含む)は、Deviseの1つによってApplicationControllerに自動的に組み込まれます初期化子は「devise.url_helpers」です。イニシャライザにはDevise gemを追加し、その内容はアプリケーションの起動時に実行されます。

深い

工夫がRailsのエンジンで行く - あなたが簡単なレビューのためにthisの記事を確認することができます。

エンジンは、ホストアプリケーションに 機能を提供する小型アプリケーションと考えることができます。 Railsアプリケーションは で、実際には「スーパーチャージ」エンジンで、Rails :: Applicationクラスの多くの動作をRails :: Engineクラスから継承しています(Rails :: Application )。

...

エンジンもプラグインに密接に関連しています。ここでの状態へ

initializer "devise.url_helpers" do 
     Devise.include_helpers(Devise::Controllers) 
    end 

initializer: -

次に、あなたが工夫のrails.rbで次の呼び出しができますhere(このrails.rbは宝石のルートdevise.rbファイルによって必要とされるが下記を参照) ではなくメソッド定義ですが、実際には文字列名パラメータとブロックパラメータでクラスメソッドを呼び出します。これはクラスロード時に実行されます(つまり、クラスをロードする結果、requireによって実行されます)。同じ時間、渡されたブロックはこの呼び出しのパラメータとして機能し、この特定の場合には後で実行されるように保存されます - 以下のイニシャライザの説明を参照してください。 (実際のrailtie中)のエンジンに

サイドノート初期のコンセプト

初期化子はRailsの基本的なクラスRailtieの一つの概念です。コンセプトはhereに記載されている:

初期化子 - Railsのブートプロセスに、あなたのRailtieから初期化ステップを追加するには、あなただけの初期化子ブロックを作成する必要があります。

# class MyRailtie < Rails::Railtie 
    #  initializer "my_railtie.configure_rails_initialization" do 
    #  # some initialization behavior 
    #  end 
    # end 

初期化子ロジックの実装がありますRailtieクラスにincludedであるInitilizablemoduleの部分。具体的な初期化子クラスメソッドは、基本的には、クラス初期化子配列sourceに渡されたブロックを追加します。

def initializer(name, opts = {}, &blk) 
    ... 
    initializers << Initializer.new(name, nil, opts, &blk) 
    end 

それはすぐに実行されていません。これはrun_initializersコールによって特定の順序でイニシャライザでrunメソッドを実行することによって実行され、Initializablemoduleの一部でもあります。このメソッドは、エンジンの継承を持つレールアプリケーション(Initializableモジュールを含む)で使用できます。

def run_initializers(group=:default, *args) 
    return if instance_variable_defined?(:@ran) 
    initializers.tsort_each do |initializer| 
    initializer.run(*args) if initializer.belongs_to?(group) 
    end 
    @ran = true 
end 

このrun_initializers方法は、アプリケーション(少し後下記参照)initialize!呼び出しによってトリガされます。

サイドノートon Rails Applicationによるのすべての収集。

一方、ここinitializersは、Applicationクラスでオーバーロードさmethodです:

def initializers #:nodoc: 
    Bootstrap.initializers_for(self) + 
    railties_initializers(super) + 
    Finisher.initializers_for(self) 
end 

この方法は、さらに発注し、実行のために、アプリケーションのすべての初期化子をロードします。 内部でrailties_initializersordered_railtiesを呼び出し、railtiesエンジンクラスのゲッター(アプリケーションは継承されます)を使用します。このゲッターはfollowing

def railties 
    @railties ||= Railties.new 
end 

Railties(複数の)サービスクラスがRailtie異なるあります。実際には、EngineクラスとRailtieクラスのすべてのサブクラスを見て、すべてrailtiesを収集します。

def initialize 
    @_all ||= ::Rails::Railtie.subclasses.map(&:instance) + 
     ::Rails::Engine.subclasses.map(&:instance) 
    end 

最後に、subclasses実行initialiersアプリケーションによって

def subclasses 
    subclasses, chain = [], descendants 
    chain.each do |k| 
     subclasses << k unless chain.any? { |c| c > k } 
    end 
    subclasses 
    end 
end 

戻す便宜上extendをレールルビー基本クラスの拡張の方法があります。前述したように、run_initializersは、Applicationクラスのinitialize!callによって呼び出されます。

のRailsアプリを environment.rbファイルに Rails.application.initialize!呼び出しによってトリガーされ
def initialize!(group=:default) #:nodoc: 
     raise "Application has been already initialized." if @initialized 
     run_initializers(group, self) 
     @initialized = true 
     self 
    end 

- それらの初期化子が実行中に追加しまっどうgenerator source

を見ますキュー?これは、Devise gemを追加することによって行われます(Bundleなど)。lib/devise.rb宝石のルート・ファイルをロードすると、一番下にrequireを次ている、)が必要です。この負荷として

require 'devise/rails' 

がクラスを考案、それがエンジンのサブクラスを見て、Railtiesクラスによって発見されます。 devise.url_helpers初期化子 を考案する

戻るあなたはinclude_helpers呼び出しを見れば、これは何それdoes次のとおりです。

def self.include_helpers(scope) 
    ActiveSupport.on_load(:action_controller) do 
     include scope::Helpers if defined?(scope::Helpers) 
     include scope::UrlHelpers 
    end 

    ActiveSupport.on_load(:action_view) do 
     include scope::UrlHelpers 
    end 
    end 

activesupportのon_loadコールは、コンポーネントをlazy_loadするRailsの機能です。 source

#1 lazy_load_hooks Railsが遅延しコンポーネント の多くを読み込むので、#速いアプリの起動を行うことができます。

この場合、コントローラーのコマンドは、コントローラーがロードされたときに実行されますが、サーバーの開始時には実行されません。コンセプトについてthisまたは他の記事をチェックしてください。

そして、これはその怠惰なブロックが実行される場所である - source

module ActionController 
    # Action Controllers are the core of a web request in \Rails. They are made up of one or more actions that are executed 
    # on request and then either it renders a template or redirects to another action. An action is defined as a public method 
    # on the controller, which will automatically be made accessible to the web-server through \Rails Routes. 
    # 
    # By default, only the ApplicationController in a \Rails application inherits from <tt>ActionController::Base</tt>. All other 
    # controllers in turn inherit from ApplicationController. This gives you one class to configure things such as 
    # request forgery protection and filtering of sensitive request parameters. 
... 
    class Base < Metal 
    ... 
    ActiveSupport.run_load_hooks(:action_controller, self) 
    end 
end 

ところで、Railsのことで生成されたあなたのApplicationControllerにはActionControllerから継承さ::ベース

+0

恐ろしい説明。ありがとうございます:) – redasus

+0

私はそれをとにかく研究したのと同じように、イニシャライザの概念に関するいくつかの注釈を追加しました。 –

+0

さらに更新されました。 Railsの機能は決して簡単ではありません。 –

関連する問題