我使用此方法选择我在post.rb
放置的类似帖子。现在我有两个问题1.我得到了一个错误。 2.我如何将这个实现到视图或控制器中以获得类似的帖子?:
class Post < ActiveRecord::Base
def similar_posts(post)
title_keywords = post.title.split(' ')
Post.all.to_a.sort do |post1, post2|
post1_title_intersection = post1.body.split(' ') & title_keywords
post2_title_intersection = post2.body.split(' ') & title_keywords
post2_title_intersection.length <=> post1_title_intersection.length
end[0..9]
end
end
我得到的错误:
syntax error, unexpected ',', expecting keyword_end Post.all.to_a.sort |post1, post2| ^
syntax error, unexpected keyword_end, expecting end-of-input
答案 0 :(得分:2)
在你的街区参数之前你错过了do
:
Post.all.to_a.sort do |post1, post2|
end
但是,你的方法存在一个主要缺陷(与你手头的语法问题无关):你要加载内存数据库中的每一个帖子 。这是一个糟糕的主意。
相反,使用某种全文如搜索,使用单独的表格作为标签,使用一些外部服务,如ElasticSearch等。这些是为此目的而制作的。
答案 1 :(得分:1)
你忘记了do
:
Post.all.to_a.sort |post1, post2|
将其实施到服务或模型中,但不实施到控制器或视图中。因为它只是严格浪费你的代码。对于服务,您可以发出延迟操作以在后台查找所需的帖子。因此,要使用延迟服务,您可以使用例如gem service
。以这种方式组织您的服务操作,您可以在使用redis
之类的缓存设施发出请求,然后存储继续执行该请求的结果。
如果您将在模型中使用它,请将其声明为方法:
class Post
def similar_posts
title_keywords = self.title.split(' ')
Post.all.sort do |post1, post2|
post1_title_intersection = post1.body.split(' ') & title_keywords
post2_title_intersection = post2.body.split(' ') & title_keywords
post2_title_intersection.length <=> post1_title_intersection.length
end[0..9]
end
然后使用它如下:
@posts = Post.find_by_id(params[:id]).similar_posts
但由于它仅用于显示,因此将其作为方法添加到decorator似乎更好。另外,为了增加访问权限,您可以使用redis
。
答案 2 :(得分:0)
您缺少执行
更改
Post.all.to_a.sort |post1, post2|
to
Post.all.to_a.sort do |post1, post2|
这将解决语法错误