【问题标题】:How do I pull a list of models (events) through a relationship with another model (Users)?如何通过与另一个模型(用户)的关系提取模型(事件)列表?
【发布时间】:2011-10-28 01:35:11
【问题描述】:

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

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

我想做的是拉出所有事件的列表

  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

谢谢!

【问题讨论】:

    标签: ruby-on-rails activerecord


    【解决方案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
    

    【讨论】:

    • 这很好用。谢谢你。有没有办法知道哪个用户与哪个事件相关?这样我就可以有一个事件列表 (event_feed) 并说明哪个用户 current_user 正在关注生成列表中的事件?
    【解决方案2】:

    事件模型:

    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
    

    【讨论】:

      【解决方案3】:

      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 #=&gt; 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}"
      

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

      【讨论】:

        猜你喜欢
        • 2014-04-02
        • 2012-05-02
        • 2011-03-26
        • 2018-12-29
        • 2021-01-07
        • 1970-01-01
        • 2021-12-09
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多