Chris Valentine
Chris Valentine

Reputation: 1637

Collection through other models Rails 4

I'm unsure how to word this as I'm not sure what the right term for this is, but..

I have a user model. This model can create Trains. such that user.trains has all their trains. This model can also create Buses, such that user.buses has all their buses. Trains and Buses can both contain Cargo. user.trains.cargo and user.buses.cargo.

How would i set this up so that I can just ask for User.cargo and get all the cargo from both the trains and the buses, without having to call the .cargo list for each?

Upvotes: 2

Views: 66

Answers (3)

Aetherus
Aetherus

Reputation: 8888

I haven't tried this but active_record_union seems promising.

class User < ActiveRecord::Base
  has_many :buses
  has_many :trains

  scope :cargoes, ->{buses.select(:cargo).union_all(trains.select(:cargo))}
end

Upvotes: 2

yez
yez

Reputation: 2378

The single table inheritance answer might be great for you, especially if Trains and Buses have mostly the same data about them. However, if those models are very different than one another you might want a different solution.

What if you defined a simple method on your user class?

class User
  has_many :trains
  has_many :buses

  def cargo
    trains.map(&:cargo) + buses.map(&:cargo)
  end
end

This answer assumes that each Bus and Train has a cargo, which is different than your example showing User.trains.cargo.

Upvotes: 2

x6iae
x6iae

Reputation: 4164

You can use the concept of Single Table inheritance in rails.

As you have both Trains and Buses, both of which can be said to be types of a Vehicle, you can have a base model Vehicle, and let both Train and Bus inherit from the Vehicle as follow:

class Vehicle < ActiveRecord::Base; end
class Train < Vehicle; end
class Bus < Vehicle; end

And then, your User class can have a one-to-many association to Cargo through Vehicle.

Like this, if you call user.cargoes (user being an instance of a User), the result should be all the cargoes of the specified user.

Hope this throws some light on the issue for you...

Upvotes: 2

Related Questions