Получить значения из 3 разных таблиц в зависимости от конкретного условия

У меня есть 3 таблицы в моей базе данных

  1. Пользователь (id, имя пользователя, электронная почта, pwd и т. д.)
  2. Производитель (id, user_id)
  3. Адрес (first_name, город, addressable_id и т. д.)

У производителя есть ссылка с таблицей пользователей (User.id = Producer.user_id) и таблицей адресов (p.id = Address.addressable_id)

Теперь я хочу получить все адреса производителей с его именем пользователя.

Я пытаюсь выполнить следующий запрос, но он не дает ожидаемого результата

select u.login, p.id, a.city from producers p

join users u on u.id = p.user_id

join addresses a on a.addressable_id = p.id

Мои модели и отношения

user.rb

class User < ActiveRecord::Base
  has_one :customer
  has_one :producer
end

producer.rb

class Producer < ActiveRecord::Base
  belongs_to :user
  belongs_to :updated_by_user, :class_name => "User", :foreign_key => "updated_by_user_id"

  has_one :address, :as => :addressable
  has_many :items  
end

address.rb

class Address < ActiveRecord::Base
  belongs_to :addressable, :polymorphic => true

  belongs_to :updated_by_user, :class_name => "User", :foreign_key => "updated_by_user_id"
end

person Raghuveer    schedule 31.10.2012    source источник
comment
Можете ли вы включить остальную часть структуры таблицы addresses? В настоящее время вы присоединяете addressable_id к producers уникальному id — вам, вероятно, следует присоединять поле producer_id в таблице addresses к producers уникальному id.   -  person    schedule 31.10.2012
comment
@MarkBannister Нет, я не добавляю поле product_id в таблицу адресов, addressable_id равен продюсеру_id   -  person Raghuveer    schedule 31.10.2012
comment
Я не говорил, что вы должны добавить поле product_id, я говорил, что, вероятно, оно уже есть — пожалуйста, перечитайте то, что я написал. Кажется немного бессмысленным иметь отдельные таблицы производителей и адресов, если у них один и тот же ключ — помните, ключ, весь ключ и ничего, кроме ключа.   -  person    schedule 31.10.2012
comment
@MarkBannister Эй, извините за мою неправильную интерпретацию. Почему я добавляю адрес в другую таблицу, потому что у меня есть разные пользователи, такие как производитель, у меня есть клиент, сотрудник и т. д., у каждого пользователя есть свой собственный адрес   -  person Raghuveer    schedule 31.10.2012


Ответы (2)


вы захотите использовать метод #select из ActiveRecord::Relation (документы).

Рельсы 3.Х:

Producer.joins(:user, :address).select("users.login, producers.id, addresses.city")

Рельсы 2.Х:

Producer.all(:joins => [:user, :address], :select => "users.login, producers.id, addresses.city")
person simonmenke    schedule 31.10.2012
comment
Ничего себе, это будет работать на rails 2.3.5?? Я попробую и дам вам знать через мгновение. Спасибо - person Raghuveer; 31.10.2012
comment
Красивый. Я люблю чистоту рубина. Я дал ответ на случай, если он захочет использовать необработанный sql. - person digaomatias; 31.10.2012
comment
@digaomatias Спасибо, я еще не пробовал это через код. Я сначала пытаюсь в SQL - person Raghuveer; 31.10.2012
comment
Кажется, в рельсах 2.3.5 нет метода соединения. - person Raghuveer; 31.10.2012
comment
Я получаю эту ошибку ActiveRecord::ConfigurationError: Ассоциация с именем «пользователи» не найдена; возможно, вы написали с ошибкой? - person Raghuveer; 31.10.2012
comment
У вас должны быть ассоциации между вашими моделями. документы - person simonmenke; 31.10.2012
comment
Я обновил свой вопрос, добавив модели с ассоциациями. Нужно ли обновлять мои модели? - person Raghuveer; 31.10.2012
comment
Спасибо за ваш пример, после выполнения которого я получаю все идентификаторы производителей, но я не получаю точный вывод - person Raghuveer; 01.11.2012

Ваш запрос выглядит нормально.

Попробуйте перейти с "join" на "left join" и посмотрите, что получится.

select u.login, p.id, a.city from producers p

left join users u on u.id = p.user_id

left join addresses a on a.addressable_id = p.id

Причина этого в том, что, возможно, один из идентификаторов отсутствует, что приводит к удалению всего результата. Если это так, вы сможете увидеть некоторые столбцы со значением NULL.

person digaomatias    schedule 31.10.2012
comment
Кстати, в mysql left join совпадает с left outer join. Внешний необязателен, но иногда для некоторых более понятен для чтения. - person Michael Durrant; 31.10.2012
comment
Я всегда использовал только левое соединение на сервере sql. Может быть, поэтому я думаю, что это понятнее, чем добавление еще одного слова для обозначения того же поведения. Просто вопрос предпочтений, я думаю. - person digaomatias; 31.10.2012