рельсы активная запись - расширенный поиск - PullRequest
0 голосов
/ 28 марта 2010

У меня есть следующая модель настройки - пользователь заинтересован в проектах во многих проектах Категории. Каждый проект имеет много категорий. Вот так:

class User
  has_many :projects
  has_and_belongs_to_many :project_categories

class Project
  belongs_to :user
  has_and_belongs_to_many :project_categories

class ProjectCategory
  has_and_belongs_to_many :projects
  has_and_belongs_to_many :users

Теперь я хотел бы найти проекты с любой из категорий. что определенный пользователь заинтересован, т.е. если пользователь заинтересован в категории проектов A, B, C, то я хотел бы найти проекты, которые являются частью одной или нескольких из этих категорий проектов.

Любой

Ответы [ 4 ]

1 голос
/ 28 марта 2010

Сначала я бы посмотрел все идентификаторы проекта для данного идентификатора пользователя, используя JOIN.

# This will give me the list of project ids for the categories that a user is interested in.
project_ids = Project.find("SELECT project_id FROM projects_project_categories JOIN project_categories_users ON project_categories_users.project_category_id = projects_project_categories.project_category_id WHERE project_categories_users.user_id = ?", user_id)

# Now that I have the list of ids I can do a simple primary key lookup. Each project object returned only has the project_id attribute populated since we only asked for the project_id above.
projects = Project.find(project_ids.collect(&:project_id))

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

Выше предполагается, что ваши таблицы соединения называются projects_project_categories и project_categories_users. Также обратите внимание, что я на самом деле не проверял это.

1 голос
/ 28 марта 2010

Для этого вам не нужен SQL, вы можете использовать встроенную функцию AR: include.

Здесь мы включаем связанные: user и: project_category, передавая определенный user_id и массив категорий, которые нас интересуют.

project = Project.find(:include => [:user, :project_categories], :conditions => {:user_id => user_id, :project_category_id => [A,B,C,D]})

Вам нужно будет настроить имена столбцов под ваши требования, но вы сможете начать с чего-то подобного.

0 голосов
/ 13 апреля 2010

Спасибо за помощь! Будучи слишком нетерпеливым нубом в данный момент, я не рассмотрел все возможные AR-решения, но было бы интересно, если что-то подобное тормозит абстракции AR, как сказал Пьер. Я пошел с измененной версией предложения Рэнди:

pids = Project.find_by_sql ["SELECT project_id FROM project_categories_projects JOIN project_categories_users ON project_categories_projects.project_category_id = project_categories_users.project_category_id WHERE user_id = ?", current_user.id]
mytags_projects = Project.find(pids.collect(&:project_id), :limit => 10, :order => "created_at DESC")
0 голосов
/ 28 марта 2010

Я полагаю, что это еще один случай утечки абстракции ActiveRecord Вам, вероятно, понадобится немного SQL для этого.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...