将列与Rails中ActiveRecord查询的结果合并



Ruby on Rails 4中有以下三个表:

"决策"表:

class Decision < ActiveRecord::Base
    validates :title,  presence: true, length: { maximum: 50 }, uniqueness: { case_sensitive: false }
    validates :colour,  presence: true, length: { maximum: 20 }, uniqueness: { case_sensitive: false }
    has_many :decision_datafields, dependent: :destroy
    has_many :datafields, through: :decision_datafields 
    def datafields
        Datafield.where(id: self.decision_datafields.select("datafield_id"))
    end 
end

"DecisionDatafield"表(链接表):

class DecisionDatafield < ActiveRecord::Base
    validates :min_score, presence: true
    validates_inclusion_of :min_score, :in => 1..10
    belongs_to :decision
    belongs_to :datafield
end    

"数据字段"表:

class Datafield < ActiveRecord::Base
    validates :title,  presence: true, length: { maximum: 100 }, uniqueness: { case_sensitive: false }
    has_many :decision_datafields, dependent: :destroy
    has_many :decisions, through: :decision_datafields  
    has_many :score_options, dependent: :destroy
    def decisions
        Decision.where(id: self.decision_datafields.select("decision_id"))
    end
end

还有一个分数选项表,但这不是解决问题的必要条件。

不管怎样,我想做的是做一个这样的查询:

Decision.first.datafields

并让ActiveRecord从DecisionDatafields链接表中检索第一个Decision的Datafields的列表以及相应的min_score值。

现在,上面的查询将返回如下内容:

#<ActiveRecord::Relation [#<Datafield id: 1, title: "DF1", created_at: "2015-03-28 09:59:26", updated_at: "2015-03-28 09:59:26">, #<Datafield id: 2, title: "DF2", created_at: "2015-03-28 09:59:26", updated_at: "2015-03-28 09:59:26">]>

这很好,但我希望它看起来像这样:

#<ActiveRecord::Relation [#<Datafield id: 1, title: "DF1", created_at: "2015-03-28 09:59:26", updated_at: "2015-03-28 09:59:26", min_score: 5>, #<Datafield id: 2, title: "DF2", created_at: "2015-03-28 09:59:26", updated_at: "2015-03-28 09:59:26, min_score: 7">]>

不同之处在于,DecisionDatafield链接表中的min_score已联接到查询返回的记录。

谢谢!

这可能有效(尚未测试):

class Decision < ActiveRecord::Base
  ...
  def data_fields
    Datafield.includes(:decision_datafield).select("datafields.*, decision_datafields.min_score").where(id: self.decision_datafields.select("datafield_id"))
  end
end

Decision.first.data_fields 调用

似乎以下方法有效:

Datafield.where(id: self.decision_datafields.select("datafield_id")).includes(:decision_datafields).joins("left join decision_datafields on datafields.id = decision_datafields.datafield_id").select("datafields.*, decision_datafields.min_score as min_score")

然而,当使用Rails控制台时,min_score似乎不会被添加到记录中。

但是,调用Decision.first.datafields.first.min_score确实会返回一个值(只是在通过Decision.first.datafields.first查看记录时没有显示)。

最新更新