Используя Rails 3, есть ли способ использования link_to helper или любого помощника, если таковой имеется, внутри модели?
Просмотреть вспомогательную ссылку link_to в классе модели
Ответ 1
Есть несколько причин, по которым вам может понадобиться link_to в модели. Да, @andy, это нарушение MVC, но это не значит, что вы должны получить очки за то, что не ответили на вопрос.
@schwabsauce, это проще, чем это. Первая строка даже не нужна, если вы делаете это в инициализаторе или что-то в этом роде. То же самое работает для .sanitize и .raw и цельной загрузки других потрясающих функций.
ActionView::Base.send(:include, Rails.application.routes.url_helpers)
ActionController::Base.helpers.link_to(whatever)
Если вы хотите использовать автопаты, вам, возможно, придется сделать это внутри вашей link_to:
Rails.application.routes.url_helpers.page_path(@page)
Ответ 2
Будьте очень осторожны, следуя советам, изложенным в сообщении Chuck, если вы делаете это в Rails 3.2.1. Казалось бы, этот подход небезопасен, включая помощник link_to в классах без просмотра в Rails 3.2.1. Существует более безопасный способ (который работает для нас в любом случае), описанный ниже.
Когда мы использовали подход на посту Чака в одном из наших классов, он оказался очень тревожным и трудно отлаживающим. Это привело к возникновению побочных эффектов/ошибок, которые появились только в очень специфических (и редких) обстоятельствах.
Проблема, насколько мы можем судить, заключается в том, что эта строка:
ActionView::Base.send(:include, Rails.application.routes.url_helpers)
Сообщает ActionView::Base
включить Rails.application.routes.url_helpers
, который ActionView::Base
, по-видимому, уже делает сам по себе. При этом он включает url_helpers
второй раз, кажется, вызывает повторную инициализацию состояния маршрутов (@_routes в классах, включенных в модуль ActionDispatch:: Routing:: UrlFor).
Это приводит к кажущимся случайным и необъяснимым "undefined методам" url_for "для исключений nil: NilClass" в представлениях, которые пытаются прямо или косвенно вызвать метод url_for после ActionView::Base
, включив url_helpers
второй время.
Решение, которое сработало для нас, состояло в том, чтобы вместо ActionView::Base
включить url_helpers
снова включить url_helpers
, просто включите модуль UrlHelper
, где бы он ни понадобился.
Затем, когда вам нужно использовать link_to и иметь доступ к пути, вы можете просто сделать это (предполагая, что login_path действителен для вашего приложения):
include ActionView::Helpers::UrlHelper
...
link = link_to('here', Rails.application.routes.url_helpers.login_path)
Нам потребовалось очень много времени и довольно много царапин на голове, чтобы отследить ошибки, вызванные двойным включением, и я просто хотел предупредить других о том, чтобы быть осторожными при настройке поведения базовых классов Rails.
Ответ 3
Я получил это для работы со следующими включениями:
include ActionView::Helpers::UrlHelper
include ActionController::UrlFor
include Rails.application.routes.url_helpers
cattr_accessor :controller
def controller; self.class.controller; end
def request; controller.request; end
Затем в моем контроллере я заполнил атрибут (создание контроллера с нуля требует значительного количества данных в хэше аргументов).
Lead.controller = self
Ответ 4
link_to helper, нарушение MVC
Что сказал Энди,
Если вы создаете HTML в модели, вам, вероятно, нужно долго смотреть на то, что вы делаете и почему.
URL-адреса помощников
URL-адреса, с другой стороны, часто полезны вне кода view-controller, во всех видах классов service/form/api/..., например, даже в моделях, если вам нужно.
Да, Rails.application.routes.url_helpers - это модуль, но это не значит, что вы должны просто включать его везде, где смешные вещи начнутся, как сказал Гэри:
https://www.destroyallsoftware.com/blog/2011/one-base-class-to-rule-them-all
Что вы можете сделать:
delegate :url_helpers, :to => 'Rails.application.routes'
а затем используйте, например,
url_helpers.home_url
Ответ 5
Не без хакеров.
Если вы думаете, что вам нужна link_to
в модели, вы, вероятно, нарушите какой-то принцип архитектуры Model-View-Controller.
Модель должна быть местом для данных и бизнес-логики, но генерация ссылок почти наверняка является заданием для контроллера или представления (или, в частности, Rails в классе-помощнике).