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
Это работает для меня. Надеюсь, вы сочтете это полезным!