2

我有一个包含一个项目的数据模型,其中包含一个建议列表,每个建议都是由用户创建的。有没有办法可以创建在项目中提出建议的所有不同用户的列表?

我正在使用 Mongoid 3。我在想这样的事情,但它不起作用:

@project = Project.find(params[:id])
@users = Array.new
@users.push(@project.suggestions.user)  <-- this doesn't work

有任何想法吗?这是我的模型结构:

class Project
  include Mongoid::Document
  has_many :suggestions, :dependent => :destroy
  ...
end

class Suggestion
  include Mongoid::Document
  belongs_to :author, class_name: "User", :inverse_of => :suggestions
  belongs_to :project
  ...
end

class User
  include Mongoid::Document
  has_many :suggestions, :inverse_of => :author
  ...
end
4

2 回答 2

1

虽然 Mongoid 可以为 MongoDB 提供关系的外观,并且 MongoDB 可以保存外键字段,但这些关系没有底层支持。以下是一些可能会帮助您获得所需解决方案的选项:

选项 1:非规范化与您的访问模式相关的数据

换句话说,复制一些数据以帮助您提高频繁类型的查询效率。您可以通过以下几种方式之一来做到这一点。

一种方法是将一个新的数组字段添加到User可能称为suggested_project_ids. 您也可以将一个新的数组字段添加到Project被调用suggesting_user_ids的 . 无论哪种情况,您都必须确保在提出建议时更新此 ObjectIds 数组。MongoDB 通过$addToSet. 然后从 Mongoid 查询看起来像这样:

User.where(suggested_project_ids: some_project_id)

选项 2:非规范化数据(类似于选项 1),但让 Mongoid 管理关系

class Project
  has_and_belongs_to_many :suggesting_users, class_name: "User", inverse_of: :suggested_projects
end

class User
  has_and_belongs_to_many :suggested_projects, class_name: "Project", inverse_of: :suggesting_users
end

从这里开始,您仍然需要在提出新建议时管理向项目添加建议用户,但您可以使用对象本身来执行此操作。Mongoid 将在后台处理设置的逻辑。之后,找到对项目提出建议的唯一用户集如下所示:

some_project.suggesting_users

选项 3:执行两个查询以获得结果

根据对每个项目提出建议的用户数量,您可能无需执行任何非规范化即可逃脱,而只需进行两次查询。

首先,获取对项目提出建议的用户 ID 列表。

author_ids = some_project.suggestions.map(&:author_id)
users = User.find(author_ids)
于 2012-08-02T15:19:26.393 回答
0

In your Project class add this :

has_many :users, :through => :suggestions

You'll then be able to do :

@users.push(@project.users)

More info on :through here :

http://api.rubyonrails.org/classes/ActiveRecord/Associations/ClassMethods.html#method-i-has_many

For mongoid, take a look at this answer : How to implement has_many :through relationships with Mongoid and mongodb?

于 2012-07-30T14:33:33.867 回答