I'm working on an ApplicationModel for a Rails app that has over 200 modules. The app is so large that when we rails s
it literally take开发者_如何学运维s 40 seconds to load our app. So in development we have a ton modules we often change and to see the changes we have to reload the app.
So I created an ApplicationModel and moved all the initializers into that model so changes are reloaded in development and we do not have to restart the server again saving lots of time everyday.
I made ApplicationModel inherit from ActiveRecord::Base
and made it an abstract class. All other models inherit from this model. So now we can put our initializers that extend ActiveRecord into this model.
Since I'm working on a project that other people started I don't know the difference between these two ways of extending ActiveRecord
and would like to know the differences between them.
ActiveRecord::Base.send(:include, someModule)
ActiveRecord::Base.extend(ClassMethods)
First, I think you're overcomplicating this a bit. If you want to reload your application's models in the console, the best choice is to just run reload!
, not a complicated custom solution.
Second, the difference between these two choices:
ActiveRecord::Base.send :include, M
ActiveRecord::Base.extend M
is that include
adds the module to the class, just as if you'd copy-pasted the instance methods in the module right into the class's definition.
By contrast, extend
will add the module to the metaclass, just as if you'd copy-pasted the instance methods in the module into a class << self
block in the class.
Here's an illustrative example:
module InstanceMethods
def foo; "foo"; end
end
class ActiveRecord::Base
include InstanceMethods
end
ActiveRecord::Base.instance_methods.include? :foo
=> true
But:
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
What you're seeing is probably:
ActiveRecord::Base.send( :include, InstanceMethods )
ActiveRecord::Base.extend( ClassMethods )
When you include a module, it's methods become instance methods in your class, when you extend a module, the module methods get inserted into the instance variable where you "extended" them. In this case, you're extending the ActiveRecord::Base "class" instance (the Class object that represents ActiveRecord::Base objects), which means these methods will become "class" methods.
You can get a full explanation about this here: "Including and extending modules in Ruby".
精彩评论