使用the Rails guides中的这个修改过的示例,一个如何使用mongoid对关系"has_many:through"关联进行建模?

挑战在于mongoid不像ActiveRecord那样支持has_many:through.

# doctor checking out patient
class Physician < ActiveRecord::Base
  has_many :appointments
  has_many :patients, :through => :appointments
  has_many :meeting_notes, :through => :appointments
end

# notes taken during the appointment
class MeetingNote < ActiveRecord::Base
  has_many :appointments
  has_many :patients, :through => :appointments
  has_many :physicians, :through => :appointments
end

# the patient
class Patient < ActiveRecord::Base
  has_many :appointments
  has_many :physicians, :through => :appointments
  has_many :meeting_notes, :through => :appointments
end

# the appointment
class Appointment < ActiveRecord::Base
  belongs_to :physician
  belongs_to :patient
  belongs_to :meeting_note
  # has timestamp attribute
end

推荐答案

Mongoid没有很多:通过或同等功能.它对MongoDB没有多大用处,因为它不支持联接查询,所以即使可以通过另一个集合引用相关集合,也需要多个查询.

https://github.com/mongoid/mongoid/issues/544

通常情况下,如果在RDBMS中有多个关系,那么在MongoDB中,您会使用一个字段来建模,该字段的两边都包含一个"外键"array.例如:

class Physician
  include Mongoid::Document
  has_and_belongs_to_many :patients
end

class Patient
  include Mongoid::Document
  has_and_belongs_to_many :physicians
end

换句话说,您将消除联接表,它将产生与has_many类似的效果:通过访问"另一端".但在您的情况下,这可能不合适,因为您的联接表是一个约会类,它包含一些额外的信息,而不仅仅是关联.

如何建模在一定程度上取决于需要运行的查询,但似乎需要添加预约模型,并定义与患者和doctor 的关联,如下所示:

class Physician
  include Mongoid::Document
  has_many :appointments
end

class Appointment
  include Mongoid::Document
  belongs_to :physician
  belongs_to :patient
end

class Patient
  include Mongoid::Document
  has_many :appointments
end

对于MongoDB中的关系,您必须在嵌入文档或关联文档之间做出 Select .在你的模型中,我猜会议笔记是一个很好的嵌入关系的候选人.

class Appointment
  include Mongoid::Document
  embeds_many :meeting_notes
end

class MeetingNote
  include Mongoid::Document
  embedded_in :appointment
end

这意味着您可以一起检索笔记和约会,而如果这是一个关联,则需要多次查询.您只需记住单个文档的16MB大小限制,如果您有大量会议记录,这可能会发挥作用.

Ruby-on-rails相关问答推荐

如何将POST-CSSS-IMPORT与TRANWIND-RACKS和IMPORT映射一起使用

params.permit ruby​​3.2.1 更新后 Active::Record 的未定义方法=~

Ruby on Rails 中的多种布局

如何确定 Rails 是从 CLI、控制台还是作为服务器运行?

如何在 Ruby on Rails 中的 cookie 上设置 HttpOnly 标志

mongoid 中 embeds_many 和 has_many 的区别

如何在 Rails 应用程序中使用长 id?

Rails data-disable-with re-enable 按钮

Rails 3.1 插件 gem、虚拟测试应用程序、rspec

Rails 3.1 Sprockets 需要指令 - 有没有办法排除特定文件?

在rails国际化yml文件中传递变量

如何为 rspec 设置 ENV 变量?

Rails 4,Capistrano 3.0.0,无法加载这样的文件 - 部署

rails respond_to format.js API

如何从另一个调用 Capistrano 任务?

我应该在 Heroku Cedar 上使用薄的还是独角兽

如何为 Rails 迁移定义布尔字段

您可以在弹性 beantalk 环境中运行 rails 控制台或 rake 命令吗?

在 Rails 中显示主机名和数据库名

为什么 rails bootstrap 这么慢,我该怎么办?