2014-11-21 3 views
0

Я загружаю данные из двух моделей, и как только данные загружаются в переменные, мне нужно удалить эти элементы из первого отношения, которые не находятся во втором.Как удалить некоторые элементы из отношения?

Образец:

users = User.all 
articles = Articles.order('created_at DESC').limit(100) 

У меня есть эти две переменные, заполненные с реляционными данными. Теперь мне нужно будет удалить из articles все предметы, где значение user_id не включено в объект users. Таким образом, в articles остались бы только предметы с user_id, то есть в переменной users.

Я пробовал его с петлей, но это было очень медленно. Как это сделать эффективно?

EDIT:

Я знаю, что есть способ избежать этого путем лучшего запроса, но в моем случае, я не могу этого сделать (хотя я согласен, что в приведенном выше примере это можно сделать). Дело в том, что у меня есть в двух переменных, загружаемых из базы данных, и мне нужно будет обрабатывать их с помощью Ruby. Есть ли команда для этого? Спасибо

ответ

0

Лучший способ сделать это, вероятно, будет с помощью SQL-соединения. Будет ли это работать?

Articles.joins(:user).order('created_at DESC').limit(100) 
+0

Благодаря @JoshBodah, я знаю, что есть способ постройте лучший запрос, но у меня уже есть данные в переменных и их необходимо обработать (я обновляю OP). – user984621

+0

Я предполагаю, что проблема заключается в том, что наивное решение только перебора коллекции и проверка '.include? 'Слишком медленная из-за размера' users'. Некоторые другие параметры, которые у вас есть, - это: 1) сортировать 'User.all' с помощью' id' и использовать двоичный поиск (Array # bsearch); 2) использовать Sets для поиска пересечения; 3) итерации при вставке в Hash для memoize вашей работы между итерациями (например, перебирать статьи и проверять, если user_id в hash еще ищет пользователей при кэшировании каждого в хэше). Бинарный подход к поиску в порядке (Set тоже может быть в порядке), но способ Hash может быть медленным. –

1

Предполагая, что вы есть belongs_to отношение на Article модели:

articles.where.not(users: users) 

Это даст вам самое большее 100, но, вероятно, меньше. Если вы хотите вернуть 100 с условием (я не проверял, но идея та же, поставить условия для пользователей в где заявление):

Articles.includes(:users).where.not(users: true).order('created_at DESC').limit(100) 
+0

Спасибо @ nikkon226. Я знаю, что есть способ создать лучший запрос, но у меня уже есть данные в переменных и нужно обрабатывать их (я обновляю OP). – user984621

+0

Не работает ли первый код? – nikkon226

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