如何通过与其他模型(用户)的关系来提取模型(事件)列表?

时间:2011-10-28 01:35:11

标签: ruby-on-rails activerecord

这有点复杂,我不知道如何实现它。我有一个用户模型和一个关系模型。用户可以“跟随”彼此(就像推特一样)。关系模型设置正确,效果很好。

接下来,我有一个事件模型。每个用户has_and_belongs_to_many事件(用户和事件之间的多对多关联)。用户“参加”活动。

我想要做的是列出所有

事件的列表
  1. 由current_user
  2. 出席 current_user正在关注的用户正在访问
  3. 如果可能,我希望通过用户模型访问此列表,以便我可以说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 个答案:

答案 0 :(得分:1)

活动模型:

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

答案 1 :(得分:1)

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}"

当然这是伪代码,但它应该让你走上正确的轨道

答案 2 :(得分:1)

这只是rails 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