检测网站视频的链接并显示标题

时间:2014-02-07 21:34:30

标签: ruby-on-rails ruby-on-rails-4

我有一个问题。

我有一个视频和评论模型。 如果用户将视频链接插入到评论中,则链接将替换为视频中的标题。

我该如何编写方法?

def to_show_title_instead_of_the_link
  body.gsub!(%r{(videos)\/([0-9])}) {|link| link_to link)}
end

我们输入:

http://localhost:3000/videos/1

我们收到:

<a href="http://localhost:3000/videos/1"> test video</a>

2 个答案:

答案 0 :(得分:2)

听起来您想要在您的网站上获取给定的网址,并找到该路线的相关参数。这样您就可以以干净,干燥的方式获取视频的id(如果您的路线发生变化,则不使用可能会在之后中断的正则表达式)。然后,这将允许您查找模型实例并获取其title字段。此任务的Rails方法是Rails.application.routes.recognize_path,它返回带有操作,控制器和路径参数的哈希。

在您看来:

# app\views\comments\show.html.erb
# ...
<div class='comment-text'>
  replace_video_url_with_anchor_tag_and_title(comment.text)
</div>
# ...

这是辅助方法:

# app\helpers\comments_helper.rb
def replace_video_url_with_anchor_tag_and_title(comment_text)
  # assuming links will end with a period, comma, exclamation point, or white space
  # this will match all links on your site
  # the part in parentheses are relative paths on your site
  # \w matches alphanumeric characters and underscores. we also need forward slashes
  regex = %r{http://your-cool-site.com(/[\w/]+)[\.,!\s]?}
  comment_text.gsub(regex) do |matched|
    # $1 gives us the portion of the regex captured by the parentheses
    params = Rails.application.routes.recognize_path $1

    # if the link we found was a video link, replaced matched string with
    # an anchor tag to the video, with the video title as the link text
    if params[:controller] == 'video' && params[:action] == 'show' 
       video = Video.find params[:id]
       link_to video.title, video_path(video)

    # otherwise just return the string without any modifications
    else
       matched
    end
  end
end

我不知道如何做到这一点,但这就是我弄清楚的:

1)Google rails reverse route,第一个结果是此stackoverflow问题:Reverse rails routing: find the the action name from the URL。答案提到了ActionController::Routing::Routes.recognize_path。我解雇了rails console然后尝试了这个,但它已被弃用,并且实际上没有用。

2)然后我google rails recognize_path。第一个搜索结果是文档,这些文档不是很有帮助。第三个搜索结果是How do you use ActionDispatch::Routing::RouteSet recognize_path?,其第二个解决方案确实有效。

3)当然,我必须重新理解Ruby正则表达式语法和gsub!,并测试我上面写的正则表达式=)

答案 1 :(得分:1)

我做了重构代码并使用了gem rinku

def links_in_body(text)
  auto_link(text) do |url|
    video_id = url.match(/\Ahttps?:\/\/#{request.host_with_port}\/videos\/(\d+)\z/)
    if video_id.present?
      Video.find(video_id[1]).title
    else
      truncate(url, length: AppConfig.truncate.length)
    end
  end
end