Question: How convert 'link_to' to Absolute in Rails

Question

How convert 'link_to' to Absolute in Rails

Answers 3
Added at 2017-09-06 17:09
Tags
Question

I've a problem in my program, I add in DB a link, for example, "www.google.com" and when I clic in the link I'm redirected to localhost:3000/www.google.com, this doesn't happen when I put "http://www.google.com" in DB.

My code

<td><%= link_to t.title, t.link_to_idea, :target => "_blank" %></td>

How do I make to convert this link always in absolute? (I think I this's solution)

Thanks!!

Answers to

How convert &#39;link_to&#39; to Absolute in Rails

nr: #1 dodano: 2017-09-06 17:09

You could do something like:

<td><%= link_to t.title, t.link_to_idea.start_with?('http') ? t.link_to_idea : "http://#{t.link_to_idea}", :target => "_blank" %></td>

..but that assumes you want all links to save with http and not https. You're probably better off checking for the protocol before you save the link in the DB.

For example, you could do what this answer suggests: Add http(s) to URL if it's not there?

before_validation :smart_add_url_protocol

protected

def smart_add_url_protocol
  unless self.url[/\Ahttp:\/\//] || self.url[/\Ahttps:\/\//]
    self.url = "http://#{self.url}"
  end
end

That way you can just do what you already have.

nr: #2 dodano: 2017-09-06 17:09

I think your best bet is to update the links in your database to all conform to a standard format. You can also add a more basic validation to make sure all links match a valid format:

validates :link_to_idea, format: URI.regexp

You can also run a backfill on your database that checks old links to make sure they match this pattern and then update the ones that do not work. Are you using MySQL?

Either way, the best answer is not to try to make your app render any-old-thing that the user puts in, but to clean the data before it gets into the database.

If you can't control what goes into the database, then I would simply render, as text, anything that doesn't match that Regexp and let users put that into their browser on their own.

nr: #3 dodano: 2017-09-09 14:09

I'd suggest that you create a decorator using Draper. This will allow you to decouple presentation logic from your domain object.

Once you've set it up then you could write something similar to this:

# app/decorators/idea_decorator.rb
class IdeaDecorator < Draper::Decorator
  delegate_all   

  def idea_url(protocol = 'https')
    return link_to_idea if has_scheme?

    "#{protocol}://#{link_to_idea}"
  end

  private

  def has_scheme?
    # .. some method here to determine if the URL has a protocol
  end
end

And used in the view:

<%= link_to t.title, t.decorate.idea_url('https') %>
Source Show
◀ Wstecz