Объединение запросов Active Record в рельсах - PullRequest
0 голосов
/ 22 марта 2011

Я пытаюсь создать фид в стиле Facebook для пользователя. Фид будет содержать последние заметки (о книгах), сделанные пользователем или людьми, за которыми пользователь следует, в сочетании с другими уведомлениями, такими как «пользователь x, за которым вы следите, начал читать новую книгу». Вы поняли идею.

Пока у меня есть класс в моем классе заметок, который возвращает нужные мне заметки:

class Note < ActiveRecord::Base
  scope :from_users_followed_by, lambda { |user| followed_by user }

  def self.followed_by(user)
    followed_ids = %(SELECT followed_id FROM relationships WHERE follower_id = :user_id)
    where("user_id IN (#{followed_ids}) OR user_id = :user_id", { :user_id => user })
  end
end

и аналогичная область в моем классе «Чтения», которая возвращает записи, созданные, когда пользователь начинает читать книгу:

class Reading < ActiveRecord::Base
  scope :from_users_followed_by, lambda { |user| followed_by(user) }

  def self.followed_by(user)
    # is this not at risk of sql injection??
    followed_ids = %(SELECT followed_id FROM relationships WHERE follower_id = :user_id)
    # return readings where user_id IN (an array of user_ids that the user follows)
    where("reader_id IN (#{followed_ids}) OR reader_id = :user_id", { :user_id => user })
  end
end

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

class User < ActiveRecord::Base
  def combined_feed
    feed = Note.from_users_followed_by(self) | Reading.from_users_followed_by(self)

    feed.sort! do |a, b|
      a.created_at <=> b.created_at
    end
    feed.reverse
  end
end

Что дает мне комбинированный корм, но кажется мне ужасно неэффективным. Как я могу сделать эквивалент на уровне базы данных в рельсах?

1 Ответ

2 голосов
/ 22 марта 2011

Я думаю, что, вероятно, создам совершенно отдельную модель под названием FeedItem.Затем, когда происходят определенные события (например, создание новой заметки), вы просто создаете новую запись FeedItem.Тогда у вас будет только одна таблица для запроса, и она будет уже в правильном порядке.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...