2011-07-24 10 views
2

私は、200以上のモジュールを持つRailsアプリケーション用のApplicationModelを開発中です。アプリがとても大きいので、rails sの場合、文字通りアプリを読み込むのに40秒かかります。開発中に頻繁に変更するモジュールがあり、アプリケーションをリロードする必要があります。ActiveRecordの拡張 - sendとextendの違いは何ですか?

私はApplicationModelを作成し、すべての初期化子をそのモデルに移動して、変更を開発時に再ロードし、毎日多くの時間を節約してサーバーを再起動する必要はありません。

ApplicationModelをActiveRecord::Baseから継承し、抽象クラスにしました。他のすべてのモデルはこのモデルから継承します。そこで、ActiveRecordを継承するイニシャライザをこのモデルに組み込むことができます。

他の人が始めたプロジェクトに取り組んでいるので、私はActiveRecordの2通りの方法の違いを知らず、それらの違いを知りたいと思います。

ActiveRecord::Base.send(:include, someModule) 
ActiveRecord::Base.extend(ClassMethods) 

答えて

7

まず、これを少し複雑にしていると思います。コンソールでアプリケーションのモデルをリロードする場合は、複雑なカスタムソリューションではなく、reload!を実行することをお勧めします。

第二に、これらの二つの選択肢の違い:

ActiveRecord::Base.send :include, M 
ActiveRecord::Base.extend M 

をコピー&ペーストしたいかのようにモジュール内のインスタンスメソッドを右クラスの定義の中に、includeがクラスにモジュールを追加することです。

対照的に、extendは、モジュールのインスタンスメソッドをクラス内のclass << selfブロックにコピーペーストしたように、モジュールをメタクラスに追加します。

module InstanceMethods 
    def foo; "foo"; end 
end 

class ActiveRecord::Base 
    include InstanceMethods 
end 

ActiveRecord::Base.instance_methods.include? :foo 
=> true 

:しかしここ

は、説明のための例です

module ClassMethods 
    def bar; "bar"; end 
end 

class ActiveRecord::Base 
    extend ClassMethods 
end 

ActiveRecord::Base.instance_methods.include? :bar 
=> false # hmm, it's not an instance method... 

ActiveRecord::Base.singleton_class.instance_methods.include? :bar 
=> true # ... it's a class method, aka an 
      # instance method on the metaclass 
+1

+1になりますように、私は自分のコードを更新していますが、最初の部分が間違ってました。リロードしようとしていたイニシャライザがありました。それらは 'config/initializers'にあったので' reload! 'はそれらに触れません。しかし、アプリケーションモデルでは、 'reload! 'が動作するか、あるいは開発中の応答しかありません。 – s84

+0

Gotcha - それは私には分かりませんでした。「200以上のモデルを持つRailsアプリケーション用のApplicationModelで作業しています。明確にしてくれてありがとう! –

+0

(ああ、数分前には "200以上のモジュール"に修正されているのがわかります) –

4

あなたが見ていることは、おそらくです:あなたはモジュールが含まれている場合、それの方法は、あなたのクラスのインスタンスメソッドになる

ActiveRecord::Base.send(:include, InstanceMethods) 
ActiveRecord::Base.extend(ClassMethods) 

あなたはモジュールを拡張する際に、モジュール方式はに挿入されますあなたがそれらを "拡張"するインスタンス変数。この場合、ActiveRecord :: Baseの "class"インスタンス(ActiveRecord :: Baseオブジェクトを表すClassオブジェクト)を拡張します。つまり、これらのメソッドは "クラス"メソッドになります。

詳細については、"Including and extending modules in Ruby"をご覧ください。

+0

右、それはより多くの意味:) – s84

関連する問題