Расширение ActiveRecord - в чем разница между отправкой, расширением? - PullRequest
2 голосов
/ 25 июля 2011

Я работаю над ApplicationModel для приложения Rails, которое имеет более 200 модулей. Приложение настолько велико, что когда мы rails s загружаем наше приложение буквально за 40 секунд. Таким образом, в процессе разработки у нас есть множество модулей, которые мы часто меняем, и чтобы увидеть изменения, нам нужно перезагрузить приложение.

Итак, я создал ApplicationModel и переместил все инициализаторы в эту модель, чтобы изменения перезагружались при разработке, и нам не нужно перезагружать сервер снова, экономя много времени каждый день.

Я сделал ApplicationModel наследованным от ActiveRecord::Base и сделал его абстрактным классом. Все остальные модели наследуются от этой модели. Так что теперь мы можем поместить наши инициализаторы, расширяющие ActiveRecord, в эту модель.

Поскольку я работаю над проектом, который начали другие люди, я не знаю разницы между этими двумя способами расширения ActiveRecord и хотел бы знать разницу между ними.

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

Ответы [ 2 ]

7 голосов
/ 25 июля 2011

Во-первых, я думаю, вы немного усложняете это. Если вы хотите перезагрузить модели вашего приложения в консоли, лучше всего просто запустить 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
4 голосов
/ 25 июля 2011

Вероятно, вы видите:

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

Когда вы включаете модуль, его методы становятся методами экземпляра в вашем классе, когда вы расширяете модуль, методы модуля вставляются в переменную экземплярагде вы их "распространили".В этом случае вы расширяете экземпляр класса «ActiveRecord :: Base» (объект Class, представляющий объекты ActiveRecord :: Base), что означает, что эти методы станут методами «класса».

полное объяснение этого здесь: «Включение и расширение модулей в Ruby» .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...