Question

I have a many-to-many relation between User and "Link".

The join model is called LinkAddress and besides for saving the IDs of the other two models, it has an attribute called address - information it collects at creation.

How can I access the address attribute for a certain link in a request scenario like the following: User.first.links.first.address ?

Models:

class User < ActiveRecord::Base
  has_many :link_addresses, dependent: :destroy
  has_many :links, through: :link_addresses
  accepts_nested_attributes_for :link_addresses, allow_destroy: true
end

class LinkAddress < ActiveRecord::Base
  belongs_to :user
  belongs_to :link
end

class Link < ActiveRecord::Base
  has_many :link_addresses, dependent: :destroy
  has_many :users, through: :link_addresses
end
Was it helpful?

Solution

You could access it through User since it's a has_many ... :through relation:

User.first.link_addresses.first.address

Or, if you'd like to go through links then:

User.first.links.first.link_addresses.first.address

OTHER TIPS

SQL Aliases

I had this exact question: Rails Scoping For has_many :through To Access Extra Data

Here's the answer I got:

    #Images
    has_many :image_messages, :class_name => 'ImageMessage'
    has_many :images, -> { select("#{Image.table_name}.*, #{ImageMessage.table_name}.caption AS caption") }, :class_name => 'Image', :through => :image_messages, dependent: :destroy

This uses SQL Aliases which I found at this RailsCast (at around 6:40 in). It allows us to call @user.image.caption (even though .caption is in the join model)


Your Code

For your query, I'd use this:

class User < ActiveRecord::Base
  has_many :link_addresses, dependent: :destroy
  has_many :links, -> { select("#{Link.table_name}.*, #{LinkAddress.table_name}.address AS address") }, through: :link_addresses

  accepts_nested_attributes_for :link_addresses, allow_destroy: true
end

This will allow you to write @user.links.first.address, and gracefully handles an absence of the address record

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top