Как вытащить список моделей (событий) через отношения с другой моделью (Пользователи)? - PullRequest
0 голосов
/ 28 октября 2011

Это немного сложно, и я не уверен, как это реализовать. У меня есть модель пользователя и модель отношений. Пользователи могут «следовать» друг за другом (как твиттер). Модель отношений настроена правильно и отлично работает.

Далее у меня есть модель Event. Каждый пользователь имеет события _________________ (многие-многие-ассоциации между пользователями и событиями). Пользователи "посещают" события.

Я хотел бы получить список всех событий, которые

  1. посещение current_user
  2. посещают пользователи, за которыми следует current_user.

Если возможно, я хотел бы, чтобы этот список был доступен через модель User, чтобы я мог сказать current_user.event_feed, и он будет перечислять все события, как упомянуто выше.

Вот мои модели:

class Event < ActiveRecord::Base
  attr_accessible :name, 
                  :description, 
                  :event_date, 
                  :location, 
                  :owner_id,
                  :category,
                  :photo

  CATEGORIES = ['Music', 'Outdoors', 'Party']

  has_and_belongs_to_many :users

и модель отношений:

class Relationship < ActiveRecord::Base
  attr_accessible :followed_id

  belongs_to :follower, :class_name => "User"
  belongs_to :followed, :class_name => "User"

  validates :follower_id, :presence => true
  validates :followed_id, :presence => true
end

и модель пользователя:

class User < ActiveRecord::Base
  # Include default devise modules. Others available are:
  # :token_authenticatable, :encryptable, :confirmable, :lockable, :timeoutable and :omniauthable
  devise :database_authenticatable, :registerable,
         :recoverable, :rememberable, :trackable, :validatable

  attr_accessible :email, :password, :password_confirmation, :remember_me
  attr_accessor :password
  attr_accessible :name, :email, :password, :password_confirmation, :time_zone

  has_and_belongs_to_many :events

  has_many :relationships, :dependent => :destroy,
                             :foreign_key => "follower_id"
  has_many :reverse_relationships, :dependent => :destroy,
                                   :foreign_key => "followed_id",
                                   :class_name => "Relationship"
  has_many :following, :through => :relationships, 
                       :source  => :followed
  has_many :followers, :through => :reverse_relationships,
                       :source  => :follower

Спасибо!

Ответы [ 3 ]

1 голос
/ 28 октября 2011

1) being attended by the current_user and Это можно сделать, просто позвонив по номеру current_user.events

2) are being attended by users that current_user is following. Это немного сложнее. Вы хотите получить плоский список событий других пользователей: current_user.following.collect { |friend| friend.events }.flatten #=> returns an array of followers' events

Поскольку вы хотите отобразить все события в одном списке (из того, что я мог бы собрать), я думаю, что класс докладчика был бы полезен:

class EventFeed
    attr_accessor :event, :display_name

   def initialize(event, name)
     self.event = event
     self.name  =  name
   end
end

А теперь, сложив их вместе, вы получите current_user.event_feed

class User
   def event_feed; []; end
end

И склеив все это:

current_user.events.each { |e| current_user.event_feed << EventFeed.new(e, 'YOU') }
current_user.following.each do |friend| 
   friend.events.each { |e| current_user.event_feed << EventFeed.new(e, friend.name) }
end

current_user.event_feed #=> an array of EventFeed objects where you can display "You are going to #{event.name}"

Конечно, это псевдокод, но он должен привести вас на правильный путь

1 голос
/ 28 октября 2011

Это только рельсы 3, но довольно элегантные (не проверенные, надеюсь, моя память об отношениях habtm в порядке).

class User < ActiveRecord::Base
  # ...

  def event_feed
    ids = self.followers.collect(&:id) << self.id
    Event.includes(:users).where(["`users`.id IN (#{ids.join(',')})"])
  end

  # ...
end
1 голос
/ 28 октября 2011

Модель события:

scope :attended, where("event_date < #{Date.today}")

Модель пользователя:

# Returns collection of events that are attended by user and users she follows
def attended events
  attended_events = []
  attended_events << events.attended
  followers.each do |follower|
    attended_events << follower.events.attended
  end
  attended_events
end
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...