ruby-on-rails - 选择不同的 rails 4.2.5 不能正常工作

标签 ruby-on-rails postgresql ruby-on-rails-4 distinct-on

我有这两个模型:

class Comment < ActiveRecord::Base
  belongs_to :post
end

class Post < ActiveRecord::Base
  include PgSearch
  has_many :comments, dependent: destroy

  pg_search_scope :search_tsv, against: [:name], 
                    using: { tsearch: { 
                              tsvector_column: 'tsv', 
                              dictionary: 'english', 
                              prefix: true, any_word: true
                             } 
                            }

 scope :full_search, ->(q) {
   select('DISTINCT ON (comments.post_id) comments.*, posts.name as post_name, posts.id as post_id')
   .order('comments.post_id, comments.created_at DESC')
   .search_tsv(q)
   .joins('LEFT JOIN comments on comments.post_id = posts.id')
 }
end

如您所见,我尝试在我的 Post 模型上实现全文搜索。我构建了 TSVECTOR 列并触发更新它,如果我只使用 search_tsv 范围,一切都像魅力一样。

但我希望搜索结果中的每个帖子都能检索最后添加的评论。为此,我构建了 full_search 范围。

当我尝试使用此作用域时,生成的 SQL 查询如下所示:

> Post.full_search('My post name').to_sql
> SELECT DISTINCT ON (comments.post_id) comments.*, 
         posts.name as post_name, potst.id as post_id 
  FROM "posts" 
  INNER JOIN (SELECT "posts"."id" AS pg_search_id, (ts_rank(("posts"."tsv"), (to_tsquery('english', ''' ' || 'My' || ' ''' || ':*') || to_tsquery('english', ''' ' || 'post' || ' ''' || ':*') || to_tsquery('english', ''' ' || 'name' || ' ''' || ':*')), 0)) AS rank FROM "posts" WHERE ((("posts"."tsv") @@ (to_tsquery('english', ''' ' || 'My' || ' ''' || ':*') || to_tsquery('english', ''' ' || 'post' || ' ''' || ':*') || to_tsquery('english', ''' ' || 'name' || ' ''' || ':*'))))) AS pg_search_00699f600cf5a0ff57479a ON "posts"."id" = pg_search_00699f600cf5a0ff57479a.pg_search_id 
 LEFT JOIN comments on comments.post_id = posts.id  
 ORDER BY comments.post_id, comments.created_at DESC, pg_search_00699f600cf5a0ff57479a.rank DESC, "posts"."id" ASC

这对我来说很好。 但是当我尝试在我的搜索 Controller 中使用这个范围时,结果很奇怪......如果我这样做:

posts = Post.full_search('My post name')
k = posts.first.comments
...

它生成这个 SQL 查询:

SELECT "comments".* FROM "comments" WHERE "comments"."post_id" = $1  ORDER BY created_at DESC, rank DESC, id DESC  [["post_id", 7]]

结果是一个空数组:(.

我不明白我做错了什么[显然我在这里做了一些愚蠢的事情:( ]。

你能帮我解决这个问题吗?

最佳答案

这意味着您的查询(复杂的查询)找到了一些帖子,第一个的 id 为 7。然后您询问了该帖子的所有评论,但没有评论。这一切似乎都井井有条。 SQL 是不同的,因为它是一个不同的问题。不是“查找带有‘我的帖子名称’的帖子”。它是“查找帖子 7 的评论”。

编辑:事情变得困惑的原因是因为您正在SELECTing comments.*,而 ActiveRecord 使用它来实例化 Post 对象(不是 Comment 对象)。所以你得到的 comments.id 是 7 并且 ActiveRecord 认为这是 Post 的 id。此外,选择 post_idpost_name 也没有意义。这应该可以防止 ActiveRecord 混淆:

   select('DISTINCT ON (comments.post_id) posts.*')

而且:由于您只搜索帖子的名称,我完全不确定您为什么要加入评论。 . . .

关于ruby-on-rails - 选择不同的 rails 4.2.5 不能正常工作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36022918/

相关文章:

ruby-on-rails - Rails 在创建和更新中使用不同的参数

ruby-on-rails - Rails::Application.initialize!方法源位置

sql - 根据行值计算行数

javascript - 尽管页面已准备好,但 Rails javascript 未触发 :load

ruby-on-rails - 这个默认的 RSpec 语句是什么意思?

ruby-on-rails - 从 id 数组更新 has_many 关联

ruby-on-rails - Rails 4.0 - method_missing : with_options issue with models

ruby-on-rails - Rails 关联在控制台中有效,但在 View 中无效

postgresql - Rosario SIS 无法连接到数据库服务器

sql - 将行添加到选择查询