简体   繁体   中英

Returning record results involving STI and Subclass Parent-Child Relationship

Bear with me for a sec...

I have two models: HorseRaceEvent and Wagerable.

Wagerable uses STI with two subclasses: Trifecta and Wager.

There's a parent-child relationship between Trifecta and Wager. For a Trifecta, there are 3 wagers associated with it. To make the association between Wager and its parent Trifecta, I use a parent_id column for the Wager record that refers to the Trifecta record. If the Wager isn't part of a Trifecta, then the parent_id is null. (parent_id for Trifecta is always null.)

So:

  • Trifecta has many wagers
  • Wager belongs to Trifecta

Now enter HorseRaceEvent.

  • HorseRaceEvent has many wagers.
  • Wager belongs to HorseRaceEvent.

NOTE: notice that the relationship with HorseRaceEvent is Wager, not Wagerable or Trifecta. (The horse_race_event_id is always null for a Trifecta record.)

HorseRaceEvent has an attribute called 'status' that can have three states: Not Started, Started, Final.

Wagerable has an attribute called 'result' that has one of three values: null, W, L.

Here's the challenge:

For the Trifecta model, I wanted to implement a named_scope or static method that returns all Trifectas in which (1) the result is null and (2) every one of its child Wager's associated HorseRaceEvent is 'Final'.

  1. I am not sure that it is cool to use STI here (I don't see whole picture, so it is just opinion). Yes, it is pretty same table structure, but different logic. So they should be separate models and tables.

  2. About your issue.

It is not very smart solution because of perfomance, but for small tables it is ok.

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

with little improvement

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

For improve perfomance and create SQL query here you can add new column to wagerables table with column wich will store true if all horse_race_event.status for each wager is Final .

Or you can write raw SQL query which will return all Trifectas with count of joined wagers is equael of count of joined wagers with joined horse_race_event status == 'Final'.

But the best solution is optimization of your architecture.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM