#ruby-on-rails
#ruby-on-rails
Вопрос:
У меня есть два приложения Rails 2.3, мы будем называть их admin и frontend. В admin у меня есть все мои модели, указанные в app/models
. В интерфейсе у меня есть символические ссылки на эти модели. Я хотел бы добавить к модели методы, специфичные для интерфейса, которые отображаются только для приложения интерфейса, а не для приложения администратора.
Сначала я попытался просто добавить config.autoload_paths = "#{RAILS_ROOT}/app/augments/address.rb"
с:
class Address
def hello
"hello world"
end
end
Но это просто не было загружено. Вызовы Address.first.hello
будут встречены undefined method 'hello'
.
Если мне потребуется файл, который делает это:
Address.class_eval do
def hello
"hello world"
end
end
Он загружается один раз, и при первом попадании в разработку он работает, но при всех последующих перезагрузках он терпит неудачу. Это связано с config.cache_classes = false
в разработке.
Полурабочее решение — запустить это из ApplicationController:
class ApplicationController < ActionController::Base
Address.class_eval do
def hello
"hello world"
end
end
end
Который перезагружается и работает каждый раз в dev andprod, но не работает для script / runner или script / console. (Если это единственное решение, я уверен, что мы могли бы извлечь это в модуль и include ModelExtensions
в ApplicationController.)
Есть ли что-то, что я могу добавить в environment.rb или инициализатор, который будет перезагружаться каждый раз при разработке?
Ответ №1:
Чтобы расширить свой класс, вы должны использовать module и включить его в свою модель. Что-то вроде этого:
module Address
def hello
"hello world"
end
end
Это старая, но всегда интересная статья по этому аргументу: http://weblog.jamisbuck.org/2007/1/17/concerns-in-activerecord
Чтобы включить модуль только во внешний интерфейс, вы должны проверить, существует ли модуль с:
Class A
include Address if defined? Address
end
Комментарии:
1. Да, но я не хочу на самом деле добавлять include AddressModelExtensions в мой address.rb, потому что это не сработало бы для моего приложения admin , поскольку модуль находится только в интерфейсе
2. ммм … да, я понял. Просто вопрос, почему вы должны использовать два разных приложения?
3. Разделение кода и загрузка. Кроме того, они будут отображаться отдельно в NewRelic, и мы потенциально можем масштабировать их отдельно.
4. Возможно, вам нужно выполнить поиск условного включения в вашей модели. Что-то вроде включить адрес, если Address.nil? . Я знаю, что это не работает … но что-то подобное
5. Вы можете проверить обновленный ответ. Я добавил определенный? и теперь должно сработать.