2013-08-13 2 views
0

Просто начните с ActiveRecord (в приложении синатра). Пытаемся связать существующие запросы с AR, но немного застряли.Тип присоединения ActiveRecord has_one Отношения

, если у меня есть HAS_ONE соотношение для пользователей и профилей (с использованием устаревших таблиц к сожалению)

class User < ActiveRecord::Base 

    self.table_name = "systemUsers" 
    self.primary_key = "user_id" 

    has_one :profile, class_name: 'Profile', foreign_key: 'profile_user_id' 
end 

class Profile < ActiveRecord::Base 

    self.table_name = "systemUserProfiles" 
    self.primary_key = "profile_id" 

    belongs_to :user, class_name: "User", foreign_key: 'user_id' 
end 

, если я хочу, чтобы запросить все пользователи с профилем, используя внутреннее соединение затем получить поле user_age из профилей используя один запрос, могу ли я это сделать?

, например (только добавил .first уменьшить код, но будет циклически всех пользователей с профилями)

user = User.all(:joins => :profile).first 
user.profile.user_age 

дает мне правильные данные и использует внутреннее соединение для первого запроса, но затем выпуски a second запрос, чтобы получить данные профиля

он также дает обесцененное предупреждение и предлагает использовать нагрузку, которую я пробовал, но не буду использовать внутреннее соединение.

подобный случай с

user = User.joins(:profile).first 
user.profile.user_age 

я получаю внутреннее соединение, но запрос для каждого пользователя строки.

Я попытался включает

user = User.includes(:profile).first 
user.profile.user_age 

This ленивым загружает профиль и позволит сократить число запросов в цикле, однако я думаю, что это будет тянуть пользователь без профиля слишком

Я также попытался с ссылка

user = User.includes(:profile).references(:profile).first 
user.profile.user_age 

Это дает мне правильные данные и снижает запросы к 1, но использует LEFT JOIN

Я, вероятно, не совсем понял это, и я пытаюсь достичь чего-то, что не подходит, я полагал, что мне может потребоваться использовать включенные и проверять нильские профили внутри цикла или использовать объединения и принимать дополнительный запрос для каждый ряд.

Думал, что я бы посмотрел, что у меня пропало что-то очевидное.

Cheers

Пат.

+0

Вероятно, следует также отметить, что я хотел бы получить доступ к всей записи профиля (не ограничивается одной области в приведенных выше примерах) – Pat

ответ

1

У профиля всегда должен быть один пользователь. Итак, я бы сделал Profile.first.user_age для первого профиля пользователя. Но идя подход пользователя, как вы делали,

User.find { |u| u.profile }.profile.user_age 

User.find { |u| u.profile } возвращает первый пользователь с true значения.

Запросить все профили пользователей и получить их user_ages. Предположим, что у всех профилей есть user_id, и это должно быть так.

Profile.pluck(:user_age) 

Это проверяет наличие user_id, если вы сохраняете профили без идентификатора пользователя. Это where.not - это новая функция в Activerecord, проверьте свою версию.

Profile.where.not(user_id: nil).pluck(:user_age) 
+0

Спасибо, К сожалению, все пользователи не обязательно имеют профили, поэтому существует внутренняя присоединяйтесь к первому первому запросу - у них должен быть профиль, но есть вероятность, что некоторые не делают :( – Pat

+0

Oh! Вот почему я дал два возможных решения :) Итак, теперь 'User.find {| u | u.profile} .profile.user_age' даст профиль 1-го пользователя. 'Profile.where.not (user_id: nil) .pluck (: user_age)' даст все пользовательские_ассы для пользователей, у которых есть профиль. 'Profile.pluck (: user_age)' также должен решить проблему. –

+0

Думайте так, у пользователя может быть или не может быть профиля. Но у ** профиля ** всегда должен быть ** пользователь **? Тогда все мое решение должно работать: D –

Смежные вопросы