`include`able ActiveRecord与其他地方的关联

时间:2015-05-10 23:26:42

标签: ruby-on-rails ruby postgresql activerecord

我有3个ActiveRecord型号:

class Doc < ActiveRecord::Base
  has_many :fields
  has_many :forms
end

class Form < ActiveRecord::Base
  belongs_to :doc
end

class Field < ActiveRecord::Base
  belongs_to :doc
end

这些模型中的每一个都有一个version列。在Doc上,它是最新版本,在FormField上,它是创建文档时的版本。查询给定表单的字段非常容易:

class Form < ActiveRecord::Base
  belongs_to :doc
  has_many :fields, ->(form) { where(version: form.version) }, through: :doc
end

我有什么方法可以构建FormField之间的关系,以便我可以急切地加载表单上的字段吗?即我希望能够说:

doc.forms.includes(:fields)

我使用Postgres作为我的数据存储。

1 个答案:

答案 0 :(得分:1)

正如上面的对话中所述,我认为使用干净的activerecord查询可能很难解决。我认为这个事实可能有点气味,并且可能会告诉您数据库结构的方式可能不是最佳的。

鉴于此,可以通过编写自定义连接来解决

has_many :version_fields, -> { joins('INNER JOIN "forms" tmp on "tmp"."version" = "fields"."version"') }, through: :doc, source: :fields

在这段代码中,我们将强制执行id约束的原始连接和强制执行该版本的自定义sql的组合。