我有一个包含项目的数据模型,其中包含一个建议列表,每个建议由用户创建。有没有办法可以创建一个在项目中提出建议的所有不同用户的列表?
我正在使用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
答案 0 :(得分:1)
虽然Mongoid可以为MongoDB提供关系,但MongoDB可以保存外键字段,但这些关系没有底层支持。以下是一些可能有助于您获得所需解决方案的选项:
选项1:对与您的访问模式相关的数据进行非规范化
换句话说,复制一些数据可以帮助您提高频繁查询类型的效率。你可以通过以下几种方式之一来做到这一点。
一种方法是将新数组字段添加到User
,可能称为suggested_project_ids
。您也可以将新数组字段添加到名为Project
的{{1}}。无论哪种情况,您都必须确保在建议时更新此ObjectIds数组。 MongoDB使$addToSet
更容易实现。从Mongoid查询然后看起来像这样:
suggesting_user_ids
选项2:对数据进行非规范化(类似于选项1),但让Mongoid管理关系
User.where(suggested_project_ids: some_project_id)
从这里开始,您仍然需要在新建议时管理向项目建议用户的添加,但您可以使用对象本身来完成。 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
选项3:执行两次查询以获得结果
根据为每个项目提出建议的用户数量,您可以在不执行任何非规范化的情况下离开,而只需进行两次查询。
首先,获取对项目提出建议的用户ID列表。
some_project.suggesting_users
答案 1 :(得分:0)
在Project
课程中添加以下内容:
has_many :users, :through => :suggestions
然后你就可以:
@users.push(@project.users)
此处:through
的更多信息:
http://api.rubyonrails.org/classes/ActiveRecord/Associations/ClassMethods.html#method-i-has_many
对于mongoid,请看一下这个答案: How to implement has_many :through relationships with Mongoid and mongodb?