Reputation: 2318
I have Favorite
model which allows Entries
and Feeds
to be saved by users.
class User < ActiveRecord::Base
has_many :favorites
has_many :favorite_feeds, :through => :favorites, :source => :favorable, :source_type => "Feed"
has_many :favorite_entries, :through => :favorites, :source => :favorable, :source_type => "Entry"
end
class Favorite < ActiveRecord::Base
belongs_to :user
belongs_to :favorable, :polymorphic => true
attr_accessible :user, :favorable
end
class Feed < ActiveRecord::Base
has_many :favorites, :as => :favorable
has_many :fans, :through => :favorites, :source => :user
end
class Entry < ActiveRecord::Base
has_many :favorites, :as => :favorable
has_many :fans, :through => :favorites, :source => :user
end
I now need to display ALL Entries
on a page and indicate whether the current_user
has added each Entry
as a favourite
. At the moment calling @entry.fans
is fetching every User
from the database, which is inefficient. I need a way of filtering this call to only fetch favorites that belong to the current_user
since I don't need any of the other records.
I can do this in memory in my controller, but I'm thinking there is a way to simply select the current_user
s favorites and join it to the Entries
model using Active::Record.
Thanks.
Upvotes: 0
Views: 449
Reputation: 9700
Controller:
@entries = Entry.all
@user_favorite_entry_ids = current_user.favorite_entries.pluck(:id)
View:
<% @entries.each do |entry| %>
<%= @entry.id %>: <%= @entry.id.in?(@user_favorite_entry_ids) ? 'favorite of current user' : 'not' %>
<% end %>
Or, if you really like doing things in the database:
@entries = Entry.select('entries.*, count(favorites.id) as current_user_favorite').joins("left join favorites on favorites.favorable_id = entries.id and favorites.favorable_type = 'Entry' and favorites.user_id = #{current_user.id}")
and then:
<% @entries.each do |entry| %>
<%= @entry.id %>: <%= (@entry.current_user_favorite.to_i > 0) ? 'favorite of current user' : 'not' %>
<% end %>
Upvotes: 1