我已经实现了一个搜索,可以搜索来自不同列的记录,但如果我使用相同的搜索字段搜索has_many(categories)表中的类别名称搜索记录,则该搜索不起作用。
我有这样的模特:
影响者:
has_many :influencer_categories, dependent: :destroy
has_many :categories, through: :influencer_categories
代码是:
控制器:
@influencers = Influencer.search(params)
型号:
def self.search(params)
.includes(:categories)
.where(search_all(params[:q]))
.where("LOWER(categories.name) like '%#{params[:q].downcase}%'")
end
def self.search_all(criteria)
if criteria.include?('@') && criteria.start_with?('@')
criteria.split(' ').map {|criterion| "LOWER(username) like '%#{criterion.downcase.gsub('@', '')}%'"}.join(' OR ')
elsif criteria.include?('#') && criteria.start_with?('#')
criteria.split(' ').map {|criterion| "LOWER(bio) like '%#{criterion.downcase.gsub('#', '')}%'"}.join(' OR ')
else
"LOWER(full_name) like '%#{criteria.downcase}%' OR LOWER(username) like '%#{criteria.downcase}%' OR LOWER(bio) like '%#{criteria.downcase}%'"
end
end
输出错误是:
ActionView::Template::Error (PG::UndefinedTable: ERROR: missing FROM-clause
entry for table "categories"
LINE 1: ... '%food%' OR LOWER(bio) like '%food%') AND (LOWER(categories...
^
: SELECT COUNT(*) FROM "influencers" WHERE (LOWER(full_name) like '%food%' OR
LOWER(username) like '%food%' OR LOWER(bio) like '%food%') AND
(LOWER(categories.name) like '%food%')):
也许我需要在我的条件中包含 OR 以获得所需的结果,因此对于食物类别,所有具有食物类别的影响者都会出现。 这就是我需要做的事情。
我相信这样的事情会起作用:
SELECT "influencers"."id" FROM "influencers" LEFT OUTER JOIN
"influencer_categories" ON "influencer_categories"."influencer_id" =
"influencers"."id" LEFT OUTER JOIN "categories" ON "categories"."id" =
"influencer_categories"."category_id" WHERE (LOWER(full_name) like '%food%' OR
LOWER(username) like '%food%' OR LOWER(bio) like '%food%' OR
LOWER(categories.name) like '%food%')
答案 0 :(得分:0)
最后,以下查询与我的关系很好:
我需要在最后或我的第一部分查询中连接has_many部分。
还需要references
来避免错误。
def self.search(params)
.includes(:categories)
.where(search_all(params[:q])+" OR LOWER(categories.name) like
'%#{params[:q].downcase}%'")
.references(:categories)
end
输出以下SQL查询:
SELECT "influencers"."id" AS t0_r0, "influencers"."instagram_id" AS t0_r1,
"influencers"."full_name" AS t0_r2, "influencers"."username" AS t0_r3,
"influencers"."profile_picture" AS t0_r4, "influencers"."website" AS t0_r5,
"influencers"."bio" AS t0_r6, "influencers"."created_at" AS t0_r7,
"influencers"."updated_at" AS t0_r8, "influencers"."slug" AS t0_r9,
"influencers"."email" AS t0_r10, "influencers"."follower_count" AS t0_r11,
"influencers"."like_count" AS t0_r12, "influencers"."comment_count" AS t0_r13,
"influencers"."media_count" AS t0_r14, "influencers"."country" AS t0_r15,
"influencers"."state" AS t0_r16, "influencers"."city" AS t0_r17,
"categories"."id" AS t1_r0, "categories"."name" AS t1_r1,
"categories"."created_at" AS t1_r2, "categories"."updated_at" AS t1_r3 FROM
"influencers" LEFT OUTER JOIN "influencer_categories" ON
"influencer_categories"."influencer_id" = "influencers"."id" LEFT OUTER JOIN
"categories" ON "categories"."id" = "influencer_categories"."category_id"
WHERE (LOWER(full_name) like '%food%' OR LOWER(username) like '%food%' OR
LOWER(bio) like '%food%' OR LOWER(categories.name) like '%food%') AND
"influencers"."id" IN (188, 189)
如果可以更优雅的方式完成,请添加您的答案或评论。