I ended up having to switch from the .group()
method (which I couldn't seem to get working with pg_search) to select("DISTINCT(stories.id), stories.*)
. I also made use of ActiveRecords#preload
so to eagerly load the associated tag records
Error thrown when trying to chain a text search with a search on a join table that uses group_by
-
04-04-2022 - |
Pregunta
I have three models, Story, Post and Tag. Story is in a one-to-many relationship with Post, and a many-to-many relationship with Tag.
I use the following scope to search for stories that have a least one tag that matches an array of tags:
scope :in_tags, lambda {|category_array, tag_array|
Story.joins('LEFT OUTER JOIN stories_tags ON stories_tags.story_id = stories.id').
joins('LEFT OUTER JOIN tags ON tags.id = stories_tags.tag_id').
where("tags.name in (:tag_array)", :tag_array => tag_array ).
group("stories.id")
}
Note that I use GROUP_BY so that the scope doesn't return a story multiple times if that story has multiple matching tags.
I use the following pg_search_scope to search for stories or posts with specified text:
pg_search_scope :with_text,
:against => :title,
:using => { :tsearch => { :dictionary => "english" }},
:associated_against => { :posts => :contents }
Both of these scopes work fine independent of each other. When I try to chain them together, however, I experience the postgreSQL error:
ActiveRecord::StatementInvalid (PG::Error: ERROR: column "pg_search_79dd68cf7f962ac568b3d7.pg_search_c5f43d73058486e1799d26" must appear in the GROUP BY clause or be used in an aggregate function
LINE 1: ...e"::text, '')) || to_tsvector('english', coalesce(pg_search_...
^
: SELECT "stories".*, ((ts_rank((to_tsvector('english', coalesce("stories"."title"::text, '')) || to_tsvector('english', coalesce(pg_search_79dd68cf7f962ac568b3d7.pg_search_c5f43d73058486e1799d26::text, ''))), (to_tsquery('english', ''' ' || 'track' || ' ''')), 0))) AS pg_search_rank FROM "stories" LEFT OUTER JOIN stories_tags ON stories_tags.story_id = stories.id LEFT OUTER JOIN tags ON tags.id = stories_tags.tag_id LEFT OUTER JOIN (SELECT "stories"."id" AS id, string_agg("posts"."contents"::text, ' ') AS pg_search_c5f43d73058486e1799d26 FROM "stories" INNER JOIN "posts" ON "posts"."story_id" = "stories"."id" GROUP BY "stories"."id") pg_search_79dd68cf7f962ac568b3d7 ON pg_search_79dd68cf7f962ac568b3d7.id = "stories"."id" WHERE (tags.name in (sports') AND (((to_tsvector('english', coalesce("stories"."title"::text, '')) || to_tsvector('english', coalesce(pg_search_79dd68cf7f962ac568b3d7.pg_search_c5f43d73058486e1799d26::text, ''))) @@ (to_tsquery('english', ''' ' || 'track' || ' ''')))) GROUP BY stories.id ORDER BY latest_post_id DESC LIMIT 5000 OFFSET 0):
Is there any way to use pg_search with a scope that requires a join table with a GROUP_BY clause?
Solución
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow