Welcome to the Treehouse Community

Want to collaborate on code errors? Have bugs you need feedback on? Looking for an extra set of eyes on your latest project? Get support with fellow developers, designers, and programmers of all backgrounds and skill levels here with the Treehouse Community! While you're at it, check out some resources Treehouse students have shared here.

Looking to learn something new?

Treehouse offers a seven day free trial for new students. Get access to thousands of hours of content and join thousands of Treehouse students and alumni in the community today.

Start your free trial

Ruby

How to count all the likes that User has done on Current_User's specific items (Rails)

I'm relatively new to Rails and SQL. I'm trying to count all the likes a User has done on my specific items. So for instance if James like 4 of my items I would like to show 4 next to James and if Lisa like 3 of my items - I would like to show 3 next to Lisa. I have listed all my relevant code below, thank you guys so much!!

Items_controller.rb

class ItemsController < ApplicationController
def index
@items = Item.order("created_at DESC")
if current_user.present?
@likersnumero = current_user.items.joins(:likes).map(&:user).count
@likers = current_user.items.map(&:likes).flatten.map(&:user).flatten.uniq
end
end

Index.html.erb

<%- @likers.each do |liker| %> 
<%= image_tag liker.avatar, width: 25, class: "css-style"  %>
<%= liker.username %>
<%= liker.likes.map(&:user).count%> ##This is as far as I could go -> It shows all likes that a User has done - I only want to show the ones for me (current_user)
<% end %>

Schema.rb

create_table "items", force: :cascade do |t|
t.string   "product"
t.integer  "user_id"
t.integer  "item_id"
t.datetime "created_at",                      null: false
t.datetime "updated_at",                      null: false
t.string   "avatar_file_name"
t.string   "avatar_content_type"
t.integer  "avatar_file_size"
t.datetime "avatar_updated_at"
t.integer  "likes_count",         default: 0, null: false
end

create_table "likes", force: :cascade do |t|
t.integer  "user_id"
t.integer  "item_id"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
end

4 Answers

Edwin Carbajal
Edwin Carbajal
4,133 Points

Hi Omar,

Assuming that an item has the foreign key of its author[current_user], the following could work.

 <%= liker.likes.select { |like| like.item.user == current_user }.count %>

You iterate the @likers and you select all of the likes of an item that has a user_id of the current user and then you do a count for the total. And rule of thumb, you want to keep away of doing long method chainings in your views and instead make a helper_method or an instance method of that Class (i.e in this case an instance method for the class 'Likes || User')

Hi Omar,

I have similar functionality on a site I mocked up late last year. I still use the site to test stuff out - I handed the production site to the designers as I'm not artistic; I have no idea if they used it or not for real.

Anyway, one part of the site has a table representing a calendar. The site admin adds events to that and a logged in user can 'like' the event. On the left & right sidebars (where the styling has gone sadly wrong) the number of people who like each event is displayed in a badge.

Have a look here and see if that's the sort of thing you're looking for - you'll need to sign into the site, I think - don't worry, the data goes nowhere. It'll email you and tweet you too, if you have a Twitter ID with your profile. If that's what you're looking for, I'll share the code with you. I used join tables to manage the many-to-many relationships between users, likes and events.

I hope it helps,

Steve.

Hi Omar,

I can see you've signed up to the demo Heroku site. You put a URL in as your Twitter handle, rather than just your @name. You should just have entered @OmarKhedr3 for it to work properly - the site sends you tweets when you sign up for events etc. It did tweet you but used the URL string rather than your handle. I need to add some validation to that field, I think.

Go to the Events page and 'like' the single event that I set up for tomorrow. You'll see how the site handles likes that way. Let me know if that's of any use to you.

Steve.

@Edwin thank you so much this was super helpful and I will definitely remember what you told me about not doing it in my views.

Hey Steve, I think I'm good but that was some awesome coding on your end looks great champ :) Edwin Carbajal has the best answer but i can't accept it for some reason weird reason so marked this one. Cheers.

No worries! :+1: :smile:

You can't mark Edwin's answer as 'best' because it isn't an answer, it's a comment. I will change that now and mark it as 'best'.

Steve.