Reputation: 8631
This is a bit complicated and I'm not sure how to implement it. I have a User model and a Relationship model. Users are able to "follow" each other (just like twitter). The relationship model is all setup properly and works great.
Next, I have an Event model. Each user has_and_belongs_to_many events (many to many association between users and events). Users "attend" events.
What I would like to do is pull a list of all events that are
If possible, I would like to have this list accessible via the User model so I can say current_user.event_feed and it will list all events as mentioned above.
Here are my models:
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
and relationship model:
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
and user model:
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
Thanks!
Upvotes: 0
Views: 311
Reputation: 14205
This is rails 3 only, but quite elegant (untested, hopefully my memory of habtm relationships is ok).
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
Upvotes: 1
Reputation: 4513
1) being attended by the current_user and
This can be achieved simply by calling current_user.events
2) are being attended by users that current_user is following.
This is a little trickier. You want to end up with a flattened list of other user's events: current_user.following.collect { |friend| friend.events }.flatten #=> returns an array of followers' events
Since you want to display all events in a single list (from what I could gather), I think a presenter class would be useful:
class EventFeed
attr_accessor :event, :display_name
def initialize(event, name)
self.event = event
self.name = name
end
end
And now, adding them together to get to current_user.event_feed
class User
def event_feed; []; end
end
And gluing it all together:
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}"
Of course this is pseudo code, but it should get you on the right track
Upvotes: 1
Reputation: 5914
Event Model:
scope :attended, where("event_date < #{Date.today}")
User Model:
# 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
Upvotes: 1