Подтвердить что ты не робот

Просмотреть вспомогательную ссылку link_to в классе модели

Используя Rails 3, есть ли способ использования link_to helper или любого помощника, если таковой имеется, внутри модели?

4b9b3361

Ответ 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 в классе-помощнике).