查询has_one是has_many的子集

时间:2019-05-15 20:18:49

标签: ruby-on-rails postgresql rails-activerecord

我有一些多态规则,可以跟踪更改,我想查询最后一个(当前)规则。我知道我可以使用belongs_to进行跟踪,但是我想保留has_one。这是模块的一部分

has_many :rule_transitions, class_name: "#{name}AppliedRuleTransition", dependent: :destroy

has_one :current_rule_transition, -> { order created_at: :desc }, class_name: "#{name}AppliedRuleTransition", inverse_of: model_name.param_key.to_sym
has_one :current_rule, through: :current_rule_transition, source: :rule

我想查询current_rule,但完整查询rule_transitions

我当前的尝试是使用postgres的FIRST_VALUE

scope :rule, lambda { |q|
  joins(:current_rule)
  .select("#{model_name.plural}.*, rules.id = FIRST_VALUE(#{model_name.param_key}_applied_rule_transitions.rule_id) OVER(PARTITION BY #{model_name.param_key}_applied_rule_transitions.id ORDER BY #{model_name.param_key}_applied_rule_transitions.created_at DESC)")
  .where(rules: { slug: q })
}

不过,我对该功能的理解不够好,但这仍然不能满足我的需求。

1 个答案:

答案 0 :(得分:1)

只需使用belongs_to并将外键放在表上即可。它将使您能够适当地渴望加载关联以避免n + 1个问题-尤其是在不希望加载整个关联的情况下想要记录列表和最新关联项的常见情况。

它的性能也将远胜于其他选择。

belongs_to :current_rule_transition, class_name: "#{name}AppliedRuleTransition"
has_many :rule_transitions, 
  class_name: "#{name}AppliedRuleTransition", 
  dependent: :destroy,
  after_add: ->(model, transition) { model.update(current_rule_transition: transition) }

无需让自己变得更困难。