【问题标题】:Merge a column with results from an ActiveRecord query in Rails在 Rails 中将列与 ActiveRecord 查询的结果合并
【发布时间】:2015-03-28 13:42:50
【问题描述】:

我在 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 链接表中检索第一个决策数据字段的列表以及相应的 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 已连接到查询返回的记录中。

谢谢!

【问题讨论】:

    标签: sql ruby-on-rails join activerecord


    【解决方案1】:

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

    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打电话

    【讨论】:

    • 谢谢,但不幸的是它返回的内容与原始查询相同。
    • 嗯,看起来datafields 方法没有被调用,而是使用了默认的活动记录关系。尝试将方法名称更改为data_fields;我更新了答案。
    • 我目前在控制台中使用这个:Datafield.includes(:decision_datafields).select("datafields.*, decision_datafields.min_score").where(id: d.decision_datafields.select("datafield_id")).first 但是,它仍然没有将“min_score”值附加到返回的记录中。
    【解决方案2】:

    似乎以下工作:

    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 查看记录时没有显示。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-04-05
      • 2018-01-31
      • 1970-01-01
      • 2010-11-12
      • 1970-01-01
      • 1970-01-01
      • 2011-02-28
      • 2019-08-06
      相关资源
      最近更新 更多