Вместо того, чтобы загружать оба набора сообщений и затем uniqing их в Ruby, вы можете сделать это немного более эффективным, имеющим SQL только дать вам уникальный список.
class User < ActiveRecord::Base
def posts
Post.where(["creator_id = ? OR updater_id = ?", self.id, self.id])
end
...
end
Причина этого является более эффективным, потому что он выдает один запрос БДА с помощью одного набора строк ответа, дубликаты никогда не возвращаются, чтобы начать с, и ActiveRecord только тогда конкретизирует объекты рубина для этого набора строк ,
Для сравнения, подход в исходном вопросе задает два запроса БД, каждый из которых создает массив из User
объектов, а затем объединяет эти два массива, а затем удаляет дубликаты. Инициализация дополнительных объектов, затем объединение массивов, а затем итерации по объединенному массиву, необходимые для удаления дубликатов, все вместе взятые, - это основная часть накладных расходов.
Как и во всех оптимизациях такого рода, если вы имеете дело с очень маленьким набором данных, разница в производительности, вероятно, незначительна, однако в этом случае единственный запрос, единственный набор ответов, является просто разумным.
На стороне записки ...
С отношениями, как это определено, если два пользователя обновить ту же должность, один за другим, не только самый последний пользователь имеет свой идентификатор, назначенный updater_id
? Это то, что вы намерены?
В зависимости от дизайна вашего приложения может быть лучше записать обновления самостоятельно, так что все пользователи, которые отредактировали данное сообщение, будут иметь этот пост в своем списке updated_posts
.
Необычно видеть «Post.name» вместо «Post». Использование строки имеет то преимущество, что не принудительно загружает модель «Post». То, что вы делаете, может непреднамеренно вводить круговые зависимости, если 'Post' имеет ссылку на' User.name'. – tadman
Ну, прибыль в том, что я использую IDE, и я могу реорганизовать имя класса без больших проблем, я не могу опечатать, из-за синтаксиса. Я пытаюсь использовать Class.name везде, где могу. Я не понял, почему зависимость так плоха, можете ли вы предоставить мне больше информации? Спасибо. – fantgeass
Если, например, 'User' имеет отношение к' Post', а 'Post' имеет отношение к' User', вы будете иметь циклическую зависимость. Класс 'User' не может полностью загрузиться до тех пор, пока' Post' не будет полностью загружен, так как вы бы указали на 'Post.name', а' Post' не может полностью загрузиться, пока не будет загружен «Пользователь», поскольку вы указали «Пользователь» .name'. Помните, что опечатки не являются проблемой, если у вас есть соответствующие модульные тесты, которые их поймают. – tadman