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