Разширете модел от Rails Engine (не го заменете)

Имам приложение на Rails, което използва скъпоценен камък, наречен ActsAsTaggableOnSteroids, който е Rails Engine. По-конкретно, използвам вилицата на ПавелНартов на скъпоценния камък. Но няма значение за това.

Трябва да добавя специфична функционалност към модела Tag, който се доставя от двигателя.

Но според моето разбиране за Rails двигателите и магическата функционалност за зареждане в Rails, ако поставя файл, наречен "tag.rb" в моята директория models, тогава той напълно ще замени този от Engine .

В идеалния случай бих могъл да направя нещо като:

class Tag < ActsAsTaggable::Tag
  # my stuff
end

... но уви, това не работи, защото моделът, предоставен от двигателя, не е с пространство от имена.

И така, измислих този кошмар, който поставих в app/models/tag.rb:

path = ActsAsTaggable::Engine.config.eager_load_paths.grep(/models/).first
require File.join(path, 'tag')
Tag.class_eval { include TagConcern }

Но трябва да има по-добър начин! Имам чувството, че нещо ми липсва. Бих предпочел да не добавям тази странност към приложението си, ако е възможно.


person Tim Morgan    schedule 28.06.2013    source източник


Отговори (1)


Просто изисквайте файла, като потърсите пътя на модела на скъпоценния камък:

require File.join(Gem::Specification.find_by_name("bborn-acts_as_taggable_on_steroids").gem_dir, 'app/models/tag')

Tag.class_eval do
  # ...
end
person aceofspades    schedule 28.06.2013
comment
Благодаря! Това със сигурност е подобрение спрямо написаното от мен. Ще изчакам още около ден, за да видя дали има по-добър, по-Rails-y начин за извършване на този вид наследяване, преди да използвам вашия отговор. - person Tim Morgan; 28.06.2013
comment
Изявлението за изискване тук е това, което гарантира, че няма да изтриете версията на скъпоценния камък. Можете да наследите от него или да използвате class_eval или да го отворите отново, както сметнете за добре. - person aceofspades; 28.06.2013