Просмотреть помощник link_to в классе Model - PullRequest
45 голосов
/ 17 января 2011

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

Ответы [ 5 ]

80 голосов
/ 18 января 2012

Есть несколько причин, по которым вам может понадобиться link_to в модели.Да, @andy, это нарушение MVC, но это не значит, что вы должны получать очки за то, что не ответили на вопрос.

@ schwabsauce, это проще, чем это.Первая строка даже не нужна, если вы делаете это в инициализаторе или что-то в этом роде.То же самое работает для .sanitize и .raw и для множества других потрясающих функций.

ActionView::Base.send(:include, Rails.application.routes.url_helpers)
ActionController::Base.helpers.link_to(whatever)

Если вы хотите использовать автоматические пути, вам может потребоваться сделать это внутри ссылки:

Rails.application.routes.url_helpers.page_path(@page)
31 голосов
/ 01 июня 2012

Будьте очень осторожны, следуя советам, изложенным в посте Чака, если вы делаете это в 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).

Это, по-видимому, приводит кслучайные и необъяснимые «неопределенные методы« url_for »для nil: NilClass» исключения в представлениях, которые пытаются вызвать, прямо или косвенно, метод url_for после того, как ActionView::Base включило url_helpers во второй раз.

Решение, которое сработало для нас, заключалось в том, чтобы вместо ActionView::Base снова включить url_helpers, просто включить модуль UrlHelper самостоятельно, где бы он вам ни понадобился.

Тогда, когда вам нужноЧтобы использовать link_to и иметь доступ к пути, вы можете просто сделать это (при условии, что login_path действителен для вашего приложения):

include ActionView::Helpers::UrlHelper
...
link = link_to('here', Rails.application.routes.url_helpers.login_path)

Нам потребовалось очень много времени и много царапин, чтобы отследитьошибки, вызванные двойным включением, и я просто хотел предупредить других, чтобы они были осторожны при настройке поведения базовых классов Rails.

5 голосов
/ 19 мая 2011

Я получил это для работы со следующими включениями:

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
3 голосов
/ 16 мая 2013

link_to helper, нарушение MVC

Что сказал Энди,

если вы генерируете HTML в модели, вам, вероятно, нужно внимательно взглянуть на то, что вы делаете и почему.

Помощники URL

С другой стороны, URL-адреса часто оказываются полезными вне кода контроллера представления, например, во всех видах классов 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
0 голосов
/ 17 января 2011

Не без взлома.

Если вы считаете, что вам нужно link_to в модели, вы, вероятно, нарушаете некоторый принцип архитектуры Model-View-Controller .

Модель должна быть местом для данных и бизнес-логики, но генерация ссылок почти наверняка является работой для контроллера или представления (или, в частности, Rails, в классе помощника).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...