Получить значение атрибута из соединения в отношении "многие ко многим"

У меня есть отношение "многие ко многим" между User и "Link".

Модель объединения называется LinkAddress и помимо сохранения идентификаторов двух других моделей у нее есть атрибут address — информация, которую она собирает при создании.

Как я могу получить доступ к атрибуту адреса для определенной ссылки в сценарии запроса, подобном следующему: User.first.links.first.address ?

Модели:

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

person Fellow Stranger    schedule 26.12.2013    source источник


Ответы (2)


Вы можете получить к нему доступ через User, так как это отношение has_many ... :through:

User.first.link_addresses.first.address

Или, если вы хотите пройти через links, то:

User.first.links.first.link_addresses.first.address
person vee    schedule 26.12.2013

Псевдонимы SQL

У меня был именно этот вопрос: Rails Scoping For has_many :through Доступ к дополнительным данным

Вот ответ, который я получил:

    #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

Это использует псевдонимы SQL, которые я нашел на этот RailsCast (около 18:40). Это позволяет нам вызывать @user.image.caption (даже несмотря на то, что .caption находится в модели соединения)


Ваш код

Для вашего запроса я бы использовал это:

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

Это позволит вам написать @user.links.first.address и изящно обработает отсутствие записи address

person Richard Peck    schedule 26.12.2013