Ruby on rails 如何在Rails中通过关联搜索组_

Ruby on rails 如何在Rails中通过关联搜索组_,ruby-on-rails,ruby,Ruby On Rails,Ruby,我不知道我是如何描述这个问题的,首先我想展示我的模型,它保持了如下的关系 category.rb class Category < ApplicationRecord has_many :job_categories, dependent: :destroy has_many :jobs, through: :job_categories end class JobCategory < ApplicationRecord belongs_to :category, co

我不知道我是如何描述这个问题的,首先我想展示我的模型,它保持了如下的关系

category.rb

class Category < ApplicationRecord
  has_many :job_categories, dependent: :destroy
  has_many :jobs, through: :job_categories
end
class JobCategory < ApplicationRecord
  belongs_to :category, counter_cache: :jobs_count
  belongs_to :job
end
父级是一个列,它维护类似组的技术,在这个ruby、rails、programming等下,它与技术相关

下面是我对按类别显示组的查询

Category.select(:id, :name, :parent).group_by{|p| p.parent}
就这样表现出来的

技术

红宝石 轨道 等 现在我想按技术显示组中的所有作业,我有一个类似这样的查询

Job.joins(:categories).where('lower(categories.parent) LIKE lower(?)', "%#{params[:parent]}%")
它显示了错误的输出,比如如果我只有一个作业,分类是ruby,rails,那么这个作业显示了两次,一次是ruby,一次是rails


谢谢

您的关联是正确的,您可以通过以下方式检索某些类别的所有唯一作业:

Job.joins(:job_categories).joins(:categories).where('lower(categories.parent) LIKE lower(?)', "%#{params[:parent]}%").distinct
这将把作业与中间表job_类别和相关键上的作业连接起来,where子句将允许您选择要检索的内容

SELECT DISTINCT "jobs" .*
FROM "jobs" INNER
JOIN "job_categories" ON "job_categories" ."job_id" = "jobs" ."id" INNER
JOIN "job_categories" "job_categories_jobs_join" ON "job_categories_jobs_join" ."job_id" = "jobs" ."id" INNER
JOIN "categories" ON "categories" ."id" = "job_categories_jobs_join" ."category_id"
WHERE
(
 lower ( categories.parent ) LIKE lower ( "Technology" ) )
更新: 实际上,我们也不需要显式连接到job_类别,以下内容就足够了:

Job.joins(:categories).where('lower(categories.parent) LIKE lower(?)', "%#{params[:parent]}%").distinct

SELECT DISTINCT "jobs".* FROM "jobs" INNER JOIN "job_categories" ON "job_categories"."job_id" = "jobs"."id" INNER JOIN "categories" ON "categories"."id" = "job_categories"."category_id" WHERE (lower ( categories.parent ) LIKE lower ( "Technology" ))

只有少数几个其他选项可用于获取和分组具有关联的记录,这些选项有很多:

# Filtering by query
Job.joins(:categories).select('jobs.id, jobs.name, categories.parent').where('lower(categories.parent) LIKE lower(?)', "Technology").distinct.inspect
# => #<ActiveRecord::Relation [#<Job id: 1, name: "Developer">, #<Job id: 2, name: "Debugger">]>

# Grouping by categories.parent, return a hash
Job.joins(:categories).select('jobs.id, jobs.name, categories.parent').all.distinct.group_by(&:parent)
# => {"Technology"=>[#<Job id: 1, name: "Developer">, #<Job id: 2, name: "Debugger">], "Mechanics"=>[#<Job id: 3, name: "Technic">]}

# Accessing the hash by key
Job.joins(:categories).select('jobs.id, jobs.name, categories.parent').all.distinct.group_by(&:parent)["Technology"]
#=> [#<Job id: 1, name: "Developer">, #<Job id: 2, name: "Debugger">]

如果只需要按顺序列出它们,为什么要应用where条件?现在显示三重而不是双重,请查看日志中的查询SELECT COUNT*from jobs INTERNAL job job job job job job job\U CATEGORES ON job\U categories job\U job\U job job\U id=job.id INTERNAL job job job job job\U categories job\U job\U job job\U CONTIEGORES ONcategories.id=job\u categories\u jobs\u join.categories\u id其中lowercategories.parent类较低的“%Technology%”添加。在关系结尾处不同。job.join:job\u categories.joins:categories.WHERE'lowercategories.parent类较低的“,%{params[:parent]}%.distinct此查询的好处是它仍然是一个ActiveRelation,使您能够与其他查询链接,并在需要时加入。
Job.joins(:categories).where('lower(categories.parent) LIKE lower(?)', "%#{params[:parent]}%").distinct

SELECT DISTINCT "jobs".* FROM "jobs" INNER JOIN "job_categories" ON "job_categories"."job_id" = "jobs"."id" INNER JOIN "categories" ON "categories"."id" = "job_categories"."category_id" WHERE (lower ( categories.parent ) LIKE lower ( "Technology" ))
# Filtering by query
Job.joins(:categories).select('jobs.id, jobs.name, categories.parent').where('lower(categories.parent) LIKE lower(?)', "Technology").distinct.inspect
# => #<ActiveRecord::Relation [#<Job id: 1, name: "Developer">, #<Job id: 2, name: "Debugger">]>

# Grouping by categories.parent, return a hash
Job.joins(:categories).select('jobs.id, jobs.name, categories.parent').all.distinct.group_by(&:parent)
# => {"Technology"=>[#<Job id: 1, name: "Developer">, #<Job id: 2, name: "Debugger">], "Mechanics"=>[#<Job id: 3, name: "Technic">]}

# Accessing the hash by key
Job.joins(:categories).select('jobs.id, jobs.name, categories.parent').all.distinct.group_by(&:parent)["Technology"]
#=> [#<Job id: 1, name: "Developer">, #<Job id: 2, name: "Debugger">]