Reputation: 143
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
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
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
Reputation: 30056
It seems your @post
is a string. Here
@post = params[:post_id]
should be
@post = Post.find(params[:post_id])
Upvotes: 1