如何定义一个变量link_to指向外部URL

46

在我的网站上,用户拥有个人资料,并带有指向他/她个人外部网站的链接。我将这些网站的URL存储在postgresql数据库中,名称为website。当我测试结果时,总是会得到一个像这样的URL:

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

而不是http://www.example.com

我的视图index.html.erb看起来像这样:

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

<%= will_paginate %>

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

<%= will_paginate %>

我的_micropost.html.erb看起来像这样:

<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>

我不知道这种情况出了什么问题。如果我在micropost.website之前加上@符号,它会给我一个错误:undefined method `website' for nil:NilClass

有人能帮帮我吗?(我是个 RoR 初学者)

KR, Fabian


3
可能是重复问题,https://dev59.com/xW445IYBdhLWcg3wJ298。该链接是用户表中类似于"user website"属性的一个外部站点URL的Rails链接。 - Luís Ramalho
不是真的。如果我在我的**_micropost.html.erb中写入<span class="website"><%= link_to micropost.website, micropost.website %></span>,我会得到一个undefined method `website' for nil:NilClass**错误。 - Fawyd
如果是这样,那么在上一行不应该先出现 undefined method title for nil:NilClass 吗? <span class="title"><%= micropost.title %></span> - Joe Frambach
@JoeFrambach 不,<%= micropost.title %> 没问题,但如果我改成 <%= @micropost.title %>,我也会得到相同的错误(但这次是针对标题)。 - Fawyd
1
那么这不是重复的吗? - Joe Frambach
@JoeFrambach 抱歉,这是一些重复的问题,但对于初学者来说比其他问题更有用。希望它可以作为新手的提示。 - Fawyd
7个回答

69

看起来您是将URL存储为没有http://的相对路径URL。您只需要像这样做:

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

或者为该模型添加一个full_url方法,如果缺少它则添加它。

顺便说一下,在那个局部文件中你不能使用 @micropost 因为它不存在(你只有@micropostsmicropost)。


1
谢谢,我已经尝试过了,它运行得很好。抱歉,对于像我这样的初学者来说,上面的答案并不清晰,无法看出我的问题与提到的其他堆栈溢出问题之间的相似之处。对不起,因为我是个新手,脑子有点笨。;-) - Fawyd

24
您可以尝试使用下面的代码: <%= link_to "您的标签", "http链接", :target => "_blank" %> 这将创建一个在新标签页中打开的链接。

1
谢谢,这很有帮助。 - bradpotts

3
您可以使用 Ruby 的 URI 类(URI::HTTP)来实现此功能。
= 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>

1
请注意,如果“网站”包含类似于“https”,“http”甚至“ftp”的协议,则会引发错误。 - cercxtrova

3
您可以这样做:
link_to micropost.website, url_for(micropost.website)

请参考Rails Api: url_for了解更多相关信息。

您可以在rails控制台中进行实验。 只需在控制台中输入:

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

你会看到一个结果字符串。

同时,你需要学习路径(path)和 URL helpers 的区别。 请参考ruby on rails指南

Goro 权限。你需要在网站属性中添加“http://”前缀。 在验证后,在将 Model 实例保存到数据库之前,你需要添加此前缀。


0

我使用postrank-uri gem在将其传递给link_to之前对URL进行规范化。

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

然后你可以在视图中使用link_to "网站", user.normalized_webpage, target: "_blank"。例如,如果URL缺少http://,它将自动添加。


0

我正在使用Rails 5,我遇到了同样的问题。我只需要在我的link_to标签中包含协议即可解决它。例如,我原来是这样写的www.google.com.mx,现在应该写成http://www.google.com.mx。就这样,它可以像官方文档中所述一样正常工作。

因此,最终我在我的视图中有了这样的代码:

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

这与以下内容相同:

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

希望能对其他人有所帮助。


-2
这是我所做的。
假设我们有一个 @person,他有一个链接 (@person.link) # => www.google.com
在你的 helpers 中创建类似于这样的东西。
def extlink(link)

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

结束

在你的文件中,你可以这样做

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

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

<% end %>

对我来说可行


2
这种方法不适用于其他协议的链接,例如https://ftp://或者 spotify:// 等广泛的应用程序协议 - 如果您想使用这种方法,也许只匹配 ://。尽管如此,最好在输入时验证URL。 - Barry
可能不是完美的,但让我有了想法。谢谢! - Juanse Cora

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接