如何在 Rails 中自动链接到文本提交中的对象

Posted

技术标签:

【中文标题】如何在 Rails 中自动链接到文本提交中的对象【英文标题】:How to automatically link to objects in text submission in Rails 【发布时间】:2012-01-26 11:27:09 【问题描述】:

因此,您在 Github 中提交了一个问题,并且您参考了问题 #31。然后,在撰写此问题时,您注意到@johnmetta 提出了一些他正在研究的可能解决方案。然后你点击“提交新问题”,当你这样做时,“#31”和“@johnmetta”是链接,@johnmetta 已经收到通知,问题 #31 有一个通知它已被引用。

我意识到这里有不止一种技术在起作用(javascript 好东西等),但我正在寻找的是如何在 Rails 世界中做这类事情的一些示例。这是一个有趣的难以搜索的主题。

我从概念上想出的是:

    有一些标识符,例如保留的# 或@ 提交后,在相应属性中搜索该标识符 找到后,搜索具有与以下内容匹配的字段的适当模型 找到后,用链接替换该文本字符串 或者,做任何必要的事情来通知被引用的对象

也就是说,它似乎超级简单(显式编码,假定为friendly_id)。

def prettify_user_links(str, source):
  result = str
  str.scan(/(@\S+)+/).each do |mtch|
    # Strip off whatever identifier we're using
    search_string = mtch[0].gsub('@','')
    # Search for the matching model in the appropriate table
    user = User.find(search_string)
    if user
      # If we find a matching model, create some link text and link it
      link_txt = "<a href=>'#user.url'>#mtch</a>"
      result.gsub!(search_string, link_txt)
      # Notification. Not sure how/where, maybe with a message bus, or something more brute-force like
      Comment.create :user_id => user.id, :body => "You have been mentioned in #link_to comment.excerpt, comment by #link_to comment.owner, owner"
  return result

那将是我的第一次剪辑,但我觉得必须有更优雅的解决方案。

这个问题的另一个方面:您将如何抓取周围文本的片段。蛮力方法是在该字符串之前搜索 n 个单词和在该字符串之后搜索 m 个单词并获取所有这些,然后从结果中获取该子字符串并进行搜索。不过,似乎会有更优雅的解决方案。

【问题讨论】:

【参考方案1】:

您所描述的是基本方法;其他任何东西都不是非常优雅。将其视为两部分是有帮助的:一个是收到评论时(应该做通知的时候),另一个是显示评论时,应该做链接。

这使您可以保留原始评论的原始形式,这很有帮助。

也许在评论模型(假设评论模型包含“body”字段)上放置一个 after_create(因此不会在每次编辑时发送通知):

[编辑:添加上下文信息]

after_create :notify_mentions

def notify_mentions
  body.scan %r(.0,40)@(\w+)(.0,20) do |match|
    username = match[1]
    context = [match.first, match.last]
    Notification.send(match, context, self) if User.exists?(:login => username)
  end
end

我用\w+ 代替\S+ 因为人们经常说这样的话:

嘿@JohnMetta,你好吗?

\S+ 将捕获可能是错误的,。将@ 拉出捕获组可以让我在通知期间忽略它。

上述匹配组中的context 由您的 sn-p 匹配用户名之前的 40 个字符和之后的 20 个字符组成。调整口味。

然后在显示消息时,您实际上创建了一个类似于您所拥有的帮助器:

def linkify(body)
  body.gsub %r@\w+ do |match|
    link_to match, :controller => :users, :action => :show, :id => match
  end
end

#gsub 非常棒,因为它需要一个块并替换为内容。

它并没有比你拥有的优雅很多,但它应该会给出一个相当不错的结果。

【讨论】:

这与我的想法非常接近,但我没有考虑将其分解为两个非常离散的步骤,并在 after_create 方法中使用通知。而且我不知道从匹配前后的正则表达式和提取文本。惊人的。非常感谢。

以上是关于如何在 Rails 中自动链接到文本提交中的对象的主要内容,如果未能解决你的问题,请参考以下文章

java如何在文本中的关键字自动加超链接

ruby on rails 固定装置中的自动关联

阻止用户返回并查看以前提交的表单Rails

如何根据 Rails 中的其他对象验证多对多关联?

在 Rails 4 中,如何在不刷新的情况下在页面上提交表单和更新元素

在 Rails 中,如何在加载子对象时自动加载父对象?