arivero
arivero

Reputation: 955

Has_many through with a parameter in Rails 5

I am struggling to manage a join table that has an integer whose purpose is to be used as an index or label over the associated records. Lets say the join table is

class Pair < ActiveRecord::Base
  belongs_to :owner
  belongs_to :element 
  validates_presence_of :position
end

With the implied setup

class Element < ActiveRecord::Base
   has_many :pairs
   has_many :owners through :pairs  
end

class Owner < ...
   has_many :pairs
   has_many :elements through :pairs
end

and position being a weight or index that ranks the elements owned by an owner

Now I want, on the collection owner.elements:

  1. Select exactly the one element with a given value of position.
  2. use owner.elements<< to create a new pairing between a known element and an owner, but at the same time giving to the link a weight/position.

The only think that I have been able to workout is to ignore through and work directly with the join_table, overloading a [] operator on it for sugar. One could expect that some more railistic solution exists, perhaps using scopes with parameters, but I do not see how I could pass a position attribute to the create or << operations.

Given that the element is perfectly idenfified by the owner and the position, a solution with some kind of dynamical parameter in has_one through would be valid too.

Upvotes: 3

Views: 531

Answers (2)

Junaid Ali
Junaid Ali

Reputation: 361

I think you should try some dry and clean approach by defining a scope in your model.

scope :by_position, ->(element) { joins(:pairs).where(pairs: { position: element.position}) }

Giving you an idea not what exactly you wish to do, But I hope this will lead to your requirements.

Upvotes: 3

Eyeslandic
Eyeslandic

Reputation: 14900

Querying is easy

owner.elements.where(pairs: { position: 1 })

adding also

element = Element.new(name: ...)
owner.pairs << Pair.create(element: element, position: 1)

Upvotes: 3

Related Questions