【问题标题】:Returning record results involving STI and Subclass Parent-Child Relationship返回涉及 STI 和子类亲子关系的记录结果
【发布时间】:2011-04-22 17:15:40
【问题描述】:

请稍等片刻……

我有两个模型:HorseRaceEvent 和 Wagerable。

Wagerable 使用具有两个子类的 STI:Trifecta 和 Wager。

Trifecta 和 Wager 之间存在父子关系。对于 Trifecta,有 3 个与之相关的投注。为了在 Wager 与其父 Trifecta 之间建立关联,我为 Wager 记录使用了 parent_id 列,该列引用了 Trifecta 记录。如果投注不是 Trifecta 的一部分,则 parent_id 为空。 (Trifecta 的 parent_id 始终为空。)

所以:

  • Trifecta 有很多赌注
  • 赌注属于 Trifecta

现在进入 HorseRaceEvent。

  • HorseRaceEvent 有很多赌注。
  • 赌注属于 HorseRaceEvent。

注意:请注意,与 HorseRaceEvent 的关系是 Wager,而不是 Wagerable 或 Trifecta。 (对于 Trifecta 记录, horse_race_event_id 始终为空。)

HorseRaceEvent 有一个名为“status”的属性,它可以具有三种状态:未开始、开始、最终。

Wagerable 有一个名为“result”的属性,它具有以下三个值之一:null、W、L。

挑战如下:

对于 Trifecta 模型,我想实现一个 named_scope 或静态方法,它返回所有 Trifecta,其中 (1) 结果为 null 并且 (2) 其子 Wager 的每个关联 HorseRaceEvent 都是“Final”。

【问题讨论】:

  • HorseRaceEvent has_one 赌注?

标签: mysql ruby-on-rails parent-child sti


【解决方案1】:
  1. 我不确定在这里使用 STI 是否很酷(我没有看到全貌,所以这只是意见)。是的,它是几乎相同的表结构,但不同的逻辑。所以它们应该是单独的模型和表。

  2. 关于您的问题。

由于性能原因,这不是很聪明的解决方案,但对于小桌子来说还可以。

class Trifecta < Wagerable
  def self.some_def_name
    Trifecta.all.select{ |t| t.wagers.all?{ |w| w.horse_race_event.status == "Final" } }
  end
end

几乎没有改进

class Trifecta < Wagerable
  def self.some_def_name
    Trifecta.includes(:wages => :horse_race_event).
      where(:wages => {:horse_race_event => {:status => "Final"}}).
      all.
      select{ |t| t.wagers.all?{ |w| w.horse_race_event.status == "Final" } }
  end
end

为了提高性能并在此处创建 SQL 查询,您可以在 wagerables 表中添加新列,如果每个 wager 的所有 horse_race_event.statusFinal,则该列将存储 true。

或者您可以编写原始 SQL 查询,该查询将返回所有 Trifectas,其中加入的赌注计数等于加入的赌注计数,加入的 horse_race_event 状态 == 'Final'。

但最好的解决方案是优化您的架构。

【讨论】:

  • 太棒了。谢谢。我真的很喜欢你关于添加一个列来跟踪事件是否是最终的建议。简单的布尔值会简化查询。
猜你喜欢
  • 1970-01-01
  • 2019-04-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多