Куда поместить общий код, найденный в многоуровневые модели?

Существует hotbackup.py сценарий, доступный на веб-сайте Подрывной деятельности, это довольно удобно для автоматизации резервных копий.

http://svn.apache.org/repos/asf/subversion/trunk/tools/backup/hot-backup.py.in

24
задан Bryan Locke 8 November 2009 в 22:59
поделиться

4 ответа

Создайте модуль, который можно поместить в каталог lib :

module Foo
  def foo
    # do something
  end
end

Затем вы можете включить модуль в каждый из классов вашей модели :

class A < ActiveRecord::Base
  include Foo
end

class B < ActiveRecord::Base
  include Foo
end

В моделях A и B теперь будет определен метод foo .

Если вы следуете соглашениям об именах Rails с именем модуля и имя файла (например, Foo в foo.rb и FooBar в foo_bar.rb), тогда Rails автоматически загрузит файл для вас. В противном случае вам нужно будет использовать require_dependency 'file_name' для загрузки вашего файла библиотеки.

37
ответ дан 28 November 2019 в 22:29
поделиться

У вас действительно есть два варианта:

  1. Использовать модуль для общей логики и включать его в A и B
  2. Использовать общий класс C, расширяющий ActiveRecord, и A и B расширять C .

Используйте # 1, если общие функции не являются основными для каждого класса, но применимы к каждому классу. Например:

(app/lib/serializable.rb)
module Serializable
  def serialize
    # do something to serialize this object
  end
end

Используйте # 2, если общие функции являются общими для каждого класса, а A и B имеют естественные отношения:

(app/models/letter.rb)
class Letter < ActiveRecord::Base
  def cyrilic_equivilent
    # return somethign similar
  end
end

class A < Letter
end

class B < Letter
end
14
ответ дан 28 November 2019 в 22:29
поделиться

Один из вариантов - поместить их в новый каталог, например app / models / modules / . Затем вы можете добавить это в config / environment.rb :

Dir["#{RAILS_ROOT}/app/models/modules/*.rb"].each do |filename|
  require filename
end

Это потребует каждого файла в этом каталоге, поэтому, если вы поместите файл, подобный следующему, в свои модули каталог:

module SharedMethods
  def foo
    #...
  end
end

Затем вы можете просто использовать его в своих моделях, потому что он будет автоматически загружен:

class User < ActiveRecord::Base
  include SharedMethods
end

Этот подход более организован, чем размещение этих миксинов в каталоге lib , потому что они находятся рядом с классами, которые используйте их.

5
ответ дан 28 November 2019 в 22:29
поделиться

Как уже упоминали другие, include Foo - это способ делать что-то ... Однако, похоже, он не дает вам функциональности, которую вы хотите, с помощью базового модуля. Ниже представлена ​​форма, которую принимают многие плагины Rails для добавления методов класса и новых обратных вызовов в дополнение к новым методам экземпляра.

module Foo #:nodoc:

  def self.included(base) # :nodoc:
    base.extend ClassMethods
  end

  module ClassMethods
    include Foo::InstanceMethods

    before_create :before_method
  end

  module InstanceMethods
    def foo
      ...
    end

    def before_method
      ...
    end
  end 

end
4
ответ дан 28 November 2019 в 22:29
поделиться
Другие вопросы по тегам:

Похожие вопросы: