2010-03-27 4 views
0

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

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 

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

Кто-нибудь?

ответ

0

Спасибо за помощь! Будучи слишком нетерпеливым noob, на данный момент я не прошел все возможные 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

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

1

Сначала я просмотрел все идентификаторы проекта для данного идентификатора пользователя, используя 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. Также обратите внимание, что я на самом деле не тестировал это.

+0

Должен сделать некоторое чтение, я думаю. Ошибка вывода моего теста на консоль ниже (494281354 - это идентификатор пользователя). --- SELECT * FROM 'projects' WHERE (' projects'.'id' IN (0,494281354)) ActiveRecord :: RecordNotFound: Не удалось найти все проекты с идентификаторами (0,494281354) (найдено 0 результатов , но искал 2) – par

+0

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

1

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

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

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

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

+0

Это правда, но недостатком является то, что это приводит к 3 SQL-запросам. Кроме того, я не уверен, есть ли у него список категорий раньше времени или если они происходят из пользовательской модели, для которой потребуется дополнительный запрос. –

+0

Иными словами, список категорий связан с пользователем, так что это будет «current_user.project_categories» – par

+0

Извините, что являетесь noob, но с проверенными конкретными user_id и A, B, C, D это дает мне «ActiveRecord :: RecordNotFound: Не удалось найти проект без ошибки ID. Поначалу я должен догадаться. – par

Смежные вопросы