首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >高级搜索查询[rails 4]

高级搜索查询[rails 4]
EN

Stack Overflow用户
提问于 2014-04-23 13:48:37
回答 1查看 177关注 0票数 0

我正试图为我的应用程序编写一个查询。我希望获得标题或所有者用户名为给定字符串的所有文章(我发送给我的方法params:word)。调查结果应按以下方法排序:

  1. 首先是current_user的条款
  2. current_user投票通过的条款
  3. 最后,其他用户的文章,但只公开一个

我的数据库看起来是:

用户有很多文章,很多选票。

一篇文章属于一个用户,有很多票。物品所有者不能投票。

投票应该与文章和用户相关联。

我的解决办法是得到我自己的文章,后来我投票通过的文章,然后是其他的公共文章。所有这些,使用3种不同的查询并将它们附加到同一个数组中,但是,也许我会在第3次查询中得到一些重复的文章。还有其他解决办法吗?也许只使用一个查询,拥有数千条记录应该是另一个问题。

任何帮助都是非常感谢的!非常感谢!!

EN

回答 1

Stack Overflow用户

发布于 2014-04-23 14:40:13

你当然可以避免重复的文章,在你的第三个查询,过滤出的文章,符合您的当前用户或有投票权,从您的当前用户。

假设你在做Article.where(article_type: 'public'),你可以做到

代码语言:javascript
复制
q = Article.where(article_type: 'public')

# Filter out articles owned by the current user
q = q.where.not(user_id: current_user.id)

# Filter out articles voted on by the current user
# This left joins the votes table to include the single row that will have
# recorded the vote for the current user on the article in question
# if the id of that left joined table is null then we know there 
# is no vote on the article for the current user and that it won't have
# been included in the second step
q = q.joins("left join votes on article_id = articles.id and user_id = #{User.sanitize(current_user.id)}"
q = q.where(votes: { id: nil })

articles = q # or q.limit(10) or somesuch

或者,正如您所说的,更理想的情况是,您希望执行一个封装您的订购需求的查询。我不知道这会有多高的效率,所以你可能需要尝试一下。有了一个查询,通过文章分页就会容易得多。(您可能还想考虑一下,一个复杂的搜索顺序是否对您的用户是明确的,以及您是否会更好地使用3种不同的搜索--但这是另一个问题)。

因此,要做到这一点,您需要一个稍微复杂一些的查询和一个更复杂的排序。我使用CASE根据您的标准设置订单:

代码语言:javascript
复制
q = Article.where("user_id = ? or article_type = 'public'", current_user.id)

# As in the query above, join in the vote row for the current user on the article
q = q.joins("left join votes on article_id = articles.id and user_id = #{User.sanitize(current_user.id)}"
q = q.where(votes: { id: nil })

# First order by whether the user is the current user or not
q = q.order("case when articles.user_id = #{User.sanitize(current_user.id)} then 1 else 2 end")

# Next order by whether the user has voted or not
q = q.order("case when votes.id is not null then 1 else 2 end")

articles = q # or q.limit(100) or q.page(1) or somesuch

order子句中的case语句将条件转换为1或2。因此,例如在第一个order子句中。如果文章的用户id与当前用户匹配,那么将使用1进行排序,否则将使用2。因此,用户的文章将出现在文章列表的较高位置。要排序的下一个标准是用户是否对文章进行投票。因此,它以类似于order by 1, 1的方式结束。

这应该可以满足您的需要(尽管我还没有测试它,所以您可能需要在这里或那里进行调整)。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/23246374

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档