46

On my site a user has a personal profile with a link to his personal external website. The url of the sites I store in a postgresql database under the name website. When I test the result, I always get a url like this:

http://localhost:3000/www.example.com

instead of http://www.example.com

My view index.html.erb looks like this:

<% provide(:title, 'All projects') %>
<h1>All projects</h1>

<%= will_paginate %>

<ul class="microposts">
    <%= render @microposts %>
</ul>

<%= will_paginate %>

and my _micropost.html.erb like this:

<li>
    <span class="title"><%= micropost.title %></span>
    <span class="website"><%= link_to micropost.website, micropost.website %></span>
    <span class="content"><%= micropost.content %></span>
    <span class="timestamp">
        Posted <%= time_ago_in_words(micropost.created_at) %> ago.
    </span>
</li>

I don't know what's the problem in this case. If I set a @ before micropost.website it gives me an error undefined method `website' for nil:NilClass

Does anyone can help me (I'm a RoR beginner)?

KR, Fabian

Fawyd
  • 1,435
  • 3
  • 13
  • 19
  • 3
    Possible duplicate http://stackoverflow.com/questions/5012188/rails-link-to-external-site-url-is-attribute-of-user-table-like-users-websit – Luís Ramalho May 23 '13 at 19:02
  • not really. If I write `<%= link_to micropost.website, micropost.website %>` in my **_micropost.html.erb**, I get also an **undefined method `website' for nil:NilClass** error – Fawyd May 23 '13 at 19:17
  • If that's the case, shouldn't you first get `undefined method title for nil:NilClass` in the line above it? `<%= micropost.title %>` – 000 May 23 '13 at 19:18
  • @JoeFrambach no, `<%= micropost.title %>` works fine, but if I would change this to `<%= @micropost.title %>` instead, I get also the same error (but this time for the title) – Fawyd May 23 '13 at 19:22
  • 1
    So how is this not a duplicate – 000 May 23 '13 at 21:56
  • @JoeFrambach sorry, this is some kind of a duplicated question, but for a beginner much more usefull than the other questions. Hope it could left as a hint for newbies. – Fawyd May 27 '13 at 19:13

7 Answers7

69

It sounds like you are storing URLs without the http:// so they are being interpreted as relative URLs. You just need to do something like this:

link_to micropost.website, "http://#{micropost.website}"

or maybe add a full_url method to that model that adds it if it's missing.

By the way, you can't use @micropost in that partial because it doesn't exist (you only have @microposts or micropost).

Leo Correa
  • 19,131
  • 2
  • 53
  • 71
Goro
  • 990
  • 8
  • 7
  • 1
    thanks, have tried this and it works well. Sorry but for me as a beginner the above answers were not clear enough to see the similarity between my problem and the problem in the mentioned other stack overflow-question. Sorry for this newbie dumb brain ;-) – Fawyd May 23 '13 at 19:28
24

You can try with this below code:

<%= link_to "your label", "your link with http", :target => "_blank" %>

This will create a link that opens in a new tab.

Chris Cirefice
  • 5,475
  • 7
  • 45
  • 75
Dimang Chou
  • 595
  • 6
  • 9
3

You can do something like that:

link_to micropost.website, url_for(micropost.website)

See Rails Api: url_for

You can experiment in rails console. Just type in console:

micropost = Micropost.first
helper.link_to micropost.website, url_for(micropost.website)

And you see a result string.

Also you need to learn the difference between path and url helpers. See ruby on rails guide.

Goro rights. You need to add "http://" to your website attribute. After validating and before save Model instance to database you need to add this prefix.

s.vatagin
  • 81
  • 1
  • 3
3

You can use the ruby URI class

= link_to micropost.website, URI::HTTP.build({:host => micropost.website}).to_s, target: "_blank"

# <a target="_blank" href="http://www.example.com">www.example.com</a>
Eric Norcross
  • 4,177
  • 4
  • 28
  • 53
  • 1
    Note that if ‘website´ contains a protocol like 'https', 'http' or even 'ftp', an error will be raised – cercxtrova Jan 06 '20 at 10:45
0

I use the postrank-uri gem to normalize the url before passing it to link_to.

class User < ActiveRecord::Base
  def normalized_webpage
    webpage && PostRank::URI.normalize(webpage).to_s
  end
end

Then you can use link_to "website", user.normalized_webpage, target: "_blank" in your view. This will for example add the http:// to the url, if it's missing.

Linus Oleander
  • 17,746
  • 15
  • 69
  • 102
0

I'm working with Rails 5 and I had the same problem. All I need to do to fix it, was to include the protocol on my link_to tag. E.g. I had www.google.com.mx, then, it should be http://www.google.com.mx. And that's it it works just fine like in the official doc is mentioned.

So, finally I just have something like this in my view:

<%= link_to (content_tag(:i, "help", class: 'material-icons tiny')), " http://www.google.com.mx", target: "_blank", rel: "alternate" %>

Which is the same as:

<%= link_to "help", "http://www.google.com.mx", target: "_blank", rel: "alternate" %>

I hope it helps somebody else.

alexventuraio
  • 8,126
  • 2
  • 30
  • 35
-2

Here's what i did.

Let's say we have @person and he has a link (@person.link) # => www.google.com

in your helpers create something like this

def extlink(link)

 if link.include?("http://")
  puts link
 else
  link.insert(0, "http://")
  link
 end

end

And in your file you can do

<% @person.each do |p| %>

<%= link_to 'External', extlink(p.link) %>

<% end %>

Works for me

  • 2
    This won't work for links to other protocols, such as `https://`, `ftp://`, or the wide range of application protocols like `spotify://` - perhaps just match `://` if you want to use this method. Having said all that though, it would be better to validate the URL on input – Barry Jun 13 '14 at 08:22
  • Maybe not perfect, but got me the idea. Thanks! – Juanse Cora Feb 04 '21 at 10:44