Как искать group_by с ассоциацией в Rails - PullRequest
0 голосов
/ 06 июня 2018

Я не знаю, как я описываю этот вопрос, сначала я хочу показать мою модель, поддерживающую отношение, как показано ниже

category.rb

class Category < ApplicationRecord
  has_many :job_categories, dependent: :destroy
  has_many :jobs, through: :job_categories
end

job.rb

class Job < ApplicationRecord
  has_many :job_categories, dependent: :destroy
  has_many :categories, through: :job_categories
end

job_category.rb

class JobCategory < ApplicationRecord
  belongs_to :category, counter_cache: :jobs_count
  belongs_to :job
end

schema.rb

create_table "categories", force: :cascade do |t|
  t.string "name"
  t.string "parent"
end

parent - это столбец, который поддерживает группу, подобную Technology и под этим ruby,rails,programming и т. Д., Который связан с технологией.

Ниже приведен мой запрос на показ группы по категориям

Category.select(:id, :name, :parent).group_by{|p| p.parent}

, и он выглядит так:

Технология

  • ruby ​​
  • rails
  • etc

Теперь я хочу показать все рабочие места в группе по Technology , У меня есть запрос для этого как

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

, и он показывает неправильный вывод, например, если у меня есть только одно задание с категориями ruby,rails, то это одно задание показывается два раза, одно для рубина и одно длярельсы.

спасибо

Ответы [ 2 ]

0 голосов
/ 06 июня 2018

Всего несколько других опций для извлечения и группировки записей с ассоциацией has_many_through:

# 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">]
0 голосов
/ 06 июня 2018

Ваши ассоциации верны, вы можете получить все уникальные задания для некоторых категорий, выполнив следующие действия:

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

Это объединит jobs с промежуточной таблицей job_categories и jobs на соответствующих клавишах.и предложение 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_categories либо должно быть достаточно:

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" ))
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...