How/When/Where Extem Gem Classes (через class_eval и модули) в Rails 3?

Каков рекомендуемый способ расширения поведения класса через class_eval и модули (а не наследованием), если я хочу расширить класс, зарытый в Gem из приложения Rails 3?

Пример:

Я хочу добавить возможность создавать постоянные ссылки для тегов и категорий (через самоцветы ActsAsTaggableOn и ActsAsCategory).

Они определили модели Tag и Category.

Я хочу в основном сделать это:

Category.class_eval do
  has_friendly_id :title
end

Tag.class_eval do
  has_friendly_id :title
end

Даже если есть другие способы добавления этой функциональности, которая может быть специфичной для драгоценного камня, каков рекомендуемый способ добавления поведения к классам в приложении Rails 3, как это?

У меня есть несколько других драгоценных камней, которые я создал, которые я хочу сделать, например, модель Configuration и модель Asset. Я хотел бы иметь возможность добавить создать класс модели app/models/configuration.rb для моего приложения, и он будет действовать так, как будто я просто сделал class_eval.

В любом случае, как это должно работать? Я не могу найти ничего, что покрывало бы это из любого из текущих Rails 3 blogs/docs/gists.

Ответ 1

Я делаю это следующим образом: сначала добавьте файл в config/initializers, где вам могут потребоваться файлы, содержащие ваши расширения:

# config/initializers/extensions.rb
require "#{Rails.root}/app/models/category.rb"
require "#{Rails.root}/app/models/tag.rb"

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

# app/models/category.rb
class Category
  has_friendly_id :title
end

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

Ответ 2

Вы можете использовать драгоценный камень rails_engine_decorator: https://github.com/atd/rails_engine_decorators

Просто добавьте в свой Gemfile:

gem 'rails_engine_decorator'

И пользователь class_eval в ваших декораторах:

/app/decorators/models/category_decorator.rb
/app/decorators/models/tag_decorator.rb

Это работает для меня. Надеюсь, вы сочтете это полезным!