0
votes

I apologize for the newbie questions still relatively new to rails. I'm trying to show all the users who have liked my specific posts. I took a look at this similar question How to list the users who LIKE a given Post but it couldn't solve my problem. I listed below all the relevant simple code - thank you so much guys!!

Items Controller

class ItemsController < ApplicationController
    before_action :authenticate_user!, only: [:new, :create]
    before_action :set_item, only: [:show, :edit, :update, :destroy, :share]

    def index    
        @items = Item.order("created_at DESC")
    end
end

Index.html.erb

<% if user_signed_in? %>
    <%= image_tag current_user.avatar, width: 70, class: "css-style"  %>
    <br>
    <strong><%= link_to current_user.username, current_user, class: "profile-style" %></strong>
    <ul><!--Trying to show all the users who have liked my specific posts here -->
    <% item.likes.each do |like| %>
  <li> <%= link_to(like.user.username, like.user) %></li>
<% end %>
</ul>
<br>
<br>
<% else %>
    <%= link_to 'Login/SignUp', new_user_session_path %>
<% end %>
<% @items.each do |item| %>
    <%= image_tag item.avatar.url(:medium), class: "block" %>
    <div>
        <%= render partial: "likes", locals: {item: item} %></span><%= item.likes_count %>
    </div>
<% end %>

Items.rb

class Item < ApplicationRecord
    has_many :likes, :counter_cache => true
    belongs_to :user
    has_attached_file :avatar, styles: { medium: "300x300>", thumb: "100x100>" }, default_url: "/images/:style/missing.png"
    validates_attachment_content_type :avatar, content_type: /\Aimage\/.*\z/
end

User.rb

class User < ApplicationRecord
    devise :database_authenticatable, :registerable,
       :recoverable, :rememberable, :trackable, :validatable, :omniauthable, omniauth_providers: [:facebook]
    has_many :likes
    has_attached_file :avatar, styles: { medium: "300x300>", thumb: "100x100>" }, default_url: "/images/:style/missing.png"
    validates_attachment_content_type :avatar, content_type: /\Aimage\/.*\z/

    def likes?(post)
        post.likes.where(user_id: id).any?
    end
end

Users Controller

class UsersController < ApplicationController
    before_action :set_user, only: [:show, :edit, :update, :destroy, :share]
    def index
        @users = User.all
    end

    def show
        @user = User.find(params[:id])
        @items = Item.all
    end

    private

    def set_user
        @user = User.find(params[:id])
    end

    def item_params
        params.require(:item).permit(:product, :amount, :city_id, :avatar)
    end
end

Like.rb

class Like < ApplicationRecord
belongs_to :item, :counter_cache => true
belongs_to :user
end

Likes Controller

class Items::LikesController < ApplicationController
before_action :authenticate_user!
before_action :set_book

def create

    @item.likes.where(user_id: current_user.id).first_or_create


    respond_to do |format|
        format.html {redirect_to @item}
        format.js
    end
end


def destroy
    @item.likes.where(user_id: current_user.id).destroy_all

    respond_to do |format|
        format.html {redirect_to @item}
        format.js
    end
end
private
def set_book
    @item = Item.find(params[:item_id])
end
end

Logs

Processing by ItemsController#index as HTML

Rendering items/index.html.erb within layouts/application User Load (0.3ms) SELECT "users".* FROM "users" WHERE "users"."id" = ? ORDER BY "users"."id" ASC LIMIT ? [["id", 1], ["LIMIT", 1]] Item Load (0.3ms) SELECT "items".* FROM "items" ORDER BY created_at DESC Rendered items/index.html.erb within layouts/application (287.6ms) Completed 500 Internal Server Error in 313ms (ActiveRecord: 0.6ms)

ActionView::Template::Error (undefined local variable or method `item' for #<#:0x007f9afbfd14f0> Did you mean? item_url items_url item_path @items): 5:
6: <%= link_to current_user.username, current_user, class: "profile-style" %> 7:

    8: <% item.likes.each do |like| %> 9:
  • <%= link_to(like.user.username, like.user) %>
  • 10: <% end %> 11:

app/views/items/index.html.erb:8:in `_app_views_items_index_html_erb___2312434021832006771_70151814680620' Rendering /usr/local/lib/ruby/gems/2.3.0/gems/actionpack-5.0.0.1/lib/action_dispatch/middleware/templates/rescues/template_error.html.erb within rescues/layout Rendering /usr/local/lib/ruby/gems/2.3.0/gems/actionpack-5.0.0.1/lib/action_dispatch/middleware/templates/rescues/_source.html.erb Rendered /usr/local/lib/ruby/gems/2.3.0/gems/actionpack-5.0.0.1/lib/action_dispatch/middleware/templates/rescues/_source.html.erb (8.3ms) Rendering /usr/local/lib/ruby/gems/2.3.0/gems/actionpack-5.0.0.1/lib/action_dispatch/middleware/templates/rescues/_trace.html.erb Rendered /usr/local/lib/ruby/gems/2.3.0/gems/actionpack-5.0.0.1/lib/action_dispatch/middleware/templates/rescues/_trace.html.erb (3.3ms) Rendering /usr/local/lib/ruby/gems/2.3.0/gems/actionpack-5.0.0.1/lib/action_dispatch/middleware/templates/rescues/_request_and_response.html.erb Rendered /usr/local/lib/ruby/gems/2.3.0/gems/actionpack-5.0.0.1/lib/action_dispatch/middleware/templates/rescues/_request_and_response.html.erb (1.2ms) Rendered /usr/local/lib/ruby/gems/2.3.0/gems/actionpack-5.0.0.1/lib/action_dispatch/middleware/templates/rescues/template_error.html.erb within rescues/layout (94.4ms)

3
In your index.html.erb you have : "<li> <%= link_to(l.user.username, l.user) %></li>" I think it should be : <li> <%= link_to(like.user.username, like.user) %></li> You never create the variable "l" anywhere but in that loop you are using |like|. Does that fix it?Rockwell Rice
@RockwellRice thank you so much for your response. when i do that I get this error undefined method `likes' for nil:NilClassOmar

3 Answers

0
votes

It's a simple mistake. I think the problem is with your partial.. you're calling the partial with locals and inside your template code you are referring to it with @item instead of item, here item is not an instance variable.

<% @items.each do |item| %>
    <%= image_tag item.avatar.url(:medium), class: "block" %>
    <div>
        <%= render partial: "likes", locals: {item: item} %></span><%= item.likes_count %>
    </div>
<% end %>

The thing is when you render a partial with locals you need to use the locals as normal variables not as instance variables.

This should work.

<% item.likes.each do |like| %>
      <li> <%= link_to(like.user.username, like.user) %></li>
<% end %>
1
votes

In items/index.html.erb you are referencing @item.likes.each on line 9, but the instance variable @item has not been set in items_controller#index. You have only defined @items, hence the error you are receiving about nil not responding to #likes.

If you want to see the likes for all items, there are a number of ways to achieve this with Arel.

0
votes

You need one more table(model) "likes" and association has-many-through. Something like this:

class Item
  has_many :likes
  has_many :users, through: :likes
end

class Like
  belongs_to :user
  belongs_to :item
end

class User
  has_many :likes
  has_many :items
  has_many :liked_items, through: :likes
end