Выбор отличного на не работает должным образом рельсы 4.2.5

У меня есть две модели:

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

который выглядит хорошо для моего. Но когда я пытаюсь использовать эту область в моем контроллере поиска, результаты странные... Если я делаю:

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]]

и результат - пустой массив:(.

Я не мог понять, что я делаю и делаю неправильно [очевидно, я делаю что-то глупое здесь:( ].

Можете ли вы помочь мне исправить это, пожалуйста?

1 ответ

Решение

Это означает, что ваш запрос (сложный) нашел несколько постов, а у первого был идентификатор 7. Затем вы запросили все комментарии к этому посту, и он не имел комментариев. Кажется, все в порядке. SQL отличается, потому что это другой вопрос. Это не "Найти сообщения с" Моим названием сообщения "." Это "Найти комментарии к посту 7".

РЕДАКТИРОВАТЬ: причина, почему все становится запутанным, потому что вы SELECTИНГ comments.*и ActiveRecord использует это для создания экземпляра Post объекты (не Comment объекты). Итак, вы получаете comments.id из 7 и ActiveRecord считает, что это идентификатор сообщения. Также нет смысла выбирать post_id а также post_name, Это должно удерживать ActiveRecord от перепутывания:

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

Но также: поскольку вы ищете только по названию поста, я не уверен, почему вы присоединяетесь к comments совсем.,,,

Другие вопросы по тегам