Florian
Florian

Reputation: 143

Display counted records from partial

I have a ruby application in which I have post and like models. I want to be able to click a like button and then refresh the number of likes for the post. For that I'm using ajax.

My question is how I can count the likes for the post in my partial html document. At the moment the code in my _show.html.erb looks like this:

<%= @post.likes.all.count %>

The div in which I would like to show the code in the index.html.erb looks like this:

<div>
        Likes: <div id="<% post.id %>_likes_output", local: :post></div>
</div>

And my create.js.erb looks like this:

$(document.getElementById("<%@post%> _likes_output").innerHTML = "<%= render partial: "likes/show", local: :post %>");

My Like create method looks like this:

def create
  @user = current_user.id
  @post = params[:post_id]
  likes = {user_id: @user, post_id: @post}
  @like = Like.new(likes)

  # a new entry in the likes table gets created
  if @like.save!
  else
    flash[:alert] = "Something went wrong"
  end
end 

At the moment I'm getting the following error:

Started POST "/posts/13/likes" for ::1 at 2019-03-22 11:38:28 +0100
Processing by LikesController#create as JS
  Parameters: {"post_id"=>"13"}
  User Load (0.2ms)  SELECT  "users".* FROM "users" WHERE "users"."id" = ? ORDER BY "users"."id" ASC LIMIT ?  [["id", 1], ["LIMIT", 1]]
  ↳ app/controllers/likes_controller.rb:4
   (0.0ms)  begin transaction
  ↳ app/controllers/likes_controller.rb:10
  Post Load (0.2ms)  SELECT  "posts".* FROM "posts" WHERE "posts"."id" = ? LIMIT ?  [["id", 13], ["LIMIT", 1]]
  ↳ app/controllers/likes_controller.rb:10
  User Load (0.1ms)  SELECT  "users".* FROM "users" WHERE "users"."id" = ? LIMIT ?  [["id", 1], ["LIMIT", 1]]
  ↳ app/controllers/likes_controller.rb:10
  Like Create (0.3ms)  INSERT INTO "likes" ("created_at", "updated_at", "user_id", "post_id") VALUES (?, ?, ?, ?)  [["created_at", "2019-03-22 10:38:28.067946"], ["updated_at", "2019-03-22 10:38:28.067946"], ["user_id", "1"], ["post_id", "13"]]
  ↳ app/controllers/likes_controller.rb:10
   (1.0ms)  commit transaction
  ↳ app/controllers/likes_controller.rb:10
  Rendering likes/create.js.erb
  Rendered likes/_show.html.erb (21.0ms)
  Rendered likes/create.js.erb (38.8ms)
Completed 500 Internal Server Error in 91ms (ActiveRecord: 1.8ms)



ActionView::Template::Error (undefined method `likes' for "13":String
Did you mean?  lines):
    1: <%= @post.likes.all.count %>

app/views/likes/_show.html.erb:1:in `_app_views_likes__show_html_erb___2777362880017156755_70224479796840'
app/views/likes/create.js.erb:3:in `_app_views_likes_create_js_erb__712898782247662482_70224408518740'

Please let me know if there is something else you need. Thank you a lot!

Upvotes: 1

Views: 118

Answers (3)

NN796
NN796

Reputation: 1267

@flo3719 there may be other issues reside in your code but the issue you mentioned ActionView::Template::Error (undefined method 'likes' for "13":String is due to the culprit line @post = params[:post_id], due to this line your @post object contains "13" in the view.

You should find your post from the database by using:

@post = Post.find_by_id(params[:post_id])

Replace your @post = params[:post_id] with below code

@post = Post.find_by_id(params[:post_id])

Upvotes: 4

wbucko
wbucko

Reputation: 95

You should find your post instead of passing id:

@post = Post.find(params[:post_id])

Also, consider using counter_cache for storing the number of likes - much better in terms of performance! https://guides.rubyonrails.org/association_basics.html#options-for-belongs-to-counter-cache

Upvotes: 0

Ursus
Ursus

Reputation: 30056

It seems your @post is a string. Here

@post = params[:post_id]

should be

@post = Post.find(params[:post_id])

Upvotes: 1

Related Questions