Marat
Marat

Reputation: 672

Using Rails association instead of instance method

I have the following now:

class Supply < ApplicationRecord
  def movements
    SupplyMovement.around_supply(self)
  end
end

class SupplyMovement < ApplicationRecord
  belongs_to :from_supply, class_name: 'Supply', optional: true
  belongs_to :to_supply, class_name: 'Supply', optional: true
    
  scope :around_supply, ->(supply) { where('from_supply_id = :supply OR to_supply_id = :supply', supply: supply.id) }

end

I'd like to have :movements association instead of movements method in Supply class. How can I do this?

Upvotes: 0

Views: 158

Answers (1)

max
max

Reputation: 102203

Its not actually possible.

In ActiveRecord each has_one / has_many association corresponds to single foreign key column on the other table. There is no way to specify assocations where the foreign key can be one of two columns.

What you can do is declare two assocations:

class Supply < ApplicationRecord
  has_many :movements_as_source, 
    class_name: 'SupplyMovement',
    foreign_key: :from_supply_id
  has_many :movements_as_destination, 
    class_name: 'SupplyMovement',
    foreign_key: :to_supply_id
end

However this won't really let you treat it as a homogenous collection.

Or you can change the table layout so that there is just a single foreign key:

class Supply < ApplicationRecord
  has_many :movements
end

class SupplyMovement < ApplicationRecord
  self.inheritance_column = 'not_type'
  belongs_to :supply
  enum :type, [:destination, :source]
end

This will let you eager load the assocation but the cost is that you'll need twice the number of rows and more complexity.

Upvotes: 1

Related Questions