1

I have a method on a model called Photo. I have it finding a selection of things from elsewhere in my app. All I need it to do at the end is to create a string of links that I can then output later on when the method is called on an instance.

My code is:

cars.map { |c| link_to(c.name, c) }.join(" AND ")

But i'm hitting this error:

undefined method `link_to' for #<Photo

Any ideas how to fix this?

rctneil
  • 7,016
  • 10
  • 40
  • 83

2 Answers2

0

link_to is a view helper which means it's only available in Rails views by default because it's a router / request concern.

If you specifically want to use link_to you have to include it or reference it directly.

See this SO answer

include ActionView::Helpers::UrlHelper
...
cars.map { |c| link_to(c.name, c) }.join(" AND ")

There are other ways of getting paths than using link_to that I would recommend you consider:

  1. It's arguable that the Rails team would tell you to use UrlFor as the tip in that link suggests:

Tip: If you need to generate URLs from your models or some other place, then ActionController::UrlFor is what you're looking for. Read on for an introduction. In general, this module should not be included on its own, as it is usually included by url_helpers (as in Rails.application.routes.url_helpers).

UrlFor also allows one to access methods that have been auto-generated from named routes.

class User < ActiveRecord::Base
  include Rails.application.routes.url_helpers

  def base_uri
    # named_route method that uses UrlFor
    user_path(self)
  end
end

User.find(1).base_uri # => "/users/1"
  1. create your own concern to bring in route helpers via ActionMailer as this article suggests

As you may see if you scroll through other SO questions about including view helpers in models, there is pushback on using router and request -based methods outside of controllers and views because it violates the principles of MVC.

I think your use case can give you some peace of mind about this, but it's worth knowing the water is murky and some people may advise you otherwise.

Chiperific
  • 4,428
  • 3
  • 21
  • 41
0

The traditional Rails wisdom (and what I'm about to give you here) is that models should not be creating HTML. They also shouldn't have methods that return HTML. Creating HTML <a> tags should be done much closer to the user interface: in a view template or maybe in a view helper. One reason is that the particular way the hyperlink should be generated is a concern of the view. (Does it need a nofollow attribute? class attributes? This will change, even from one view to another.) And the model should not have any knowledge of these details.

When you do generate links in the views, then you have access to all the helpers such as link_to.

Instead, as I understand it, a model should be responsible for returning its own data. Maybe in your case that'd be an array of dicts of :label, :url. I.e., pure data that'd be easy to pass to link_to.

Hope that helps!

Dogweather
  • 15,512
  • 17
  • 62
  • 81