返回涉及STI和子类父子关系的记录结果

时间:2011-04-22 17:15:40

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

忍受我一阵......

我有两个模型:HorseRaceEvent和Wagerable。

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

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

所以:

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

现在输入HorseRaceEvent。

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

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

HorseRaceEvent有一个名为'status'的属性,可以有三种状态:Not Started,Started,Final。

Wagerable有一个名为'result'的属性,它有三个值之一:null,W,L。

这是挑战:

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

1 个答案:

答案 0 :(得分:0)

  1. 我不确定在这里使用STI很酷(我看不到全貌,所以只是意见)。是的,它与表结构完全相同,但逻辑不同。所以它们应该是单独的模型和表格。

  2. 关于您的问题。

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

    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表添加新列,如果每个horse_race_event.status的所有wager都为Final,则列将存储为true。

    或者您可以编写原始SQL查询,该查询将返回所有加入投注计数的Trifectas与已加入的投注计数的等于加入的horse_race_event status =='Final'。

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