rails active record - 高级查找

时间:2010-03-27 21:48:07

标签: sql ruby-on-rails activerecord

我有以下模型设置 - 用户对许多项目中的项目感兴趣 分类。每个项目都有很多类别。像这样:

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 个答案:

答案 0 :(得分:1)

首先,我会使用JOIN查找给定用户ID的所有项目ID。

# 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 :(得分:1)

您不需要SQL来执行此操作,您可以使用AR的bult-in: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]})

您需要根据您的要求调整列名称,但您应该能够从这样的事情开始。

答案 2 :(得分:0)

我相信这是ActiveRecord抽象泄漏的另一个例子。你可能需要一些SQL才能做到这一点。

答案 3 :(得分:0)

感谢您的帮助!作为一个过于热切的菜鸟,我还没有经历过所有可能的AR解决方案,但如果像皮埃尔所说的那样这样的东西制动了AR的抽象,那将会很有趣。我选择了Randy建议的修改版本:

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")