2
\$\begingroup\$

I want to distinguish between people who have likes to posts and those who have dislikes. I want to find a way to improve my code without thinking it is efficient.

<% if current_user.voted_up_on? @post %>
  <%= link_to "LIKE #{@post.get_upvotes.size}", like_post_path(@post), method: :post, class: "btn btn-outline-primary" %>
  <%= link_to "DISLIKE #{@post.get_downvotes.size}", dislike_post_path(@post), method: :post, class: "btn btn-outline-dark" %>
<% elsif current_user.voted_down_on? @post %>
  <%= link_to "LIKE #{@post.get_upvotes.size}", like_post_path(@post), method: :post, class: "btn btn-outline-dark" %>
  <%= link_to "DISLIKE #{@post.get_downvotes.size}", dislike_post_path(@post), method: :post, class: "btn btn-outline-danger" %>
<% else %>
  <%= link_to "LIKE #{@post.get_upvotes.size}", like_post_path(@post), method: :post, class: "btn btn-outline-dark" %>
  <%= link_to "DISLIKE #{@post.get_downvotes.size}", dislike_post_path(@post), method: :post, class: "btn btn-outline-dark" %>
<% end %>
\$\endgroup\$

2 Answers 2

0
\$\begingroup\$

I cam think of a couple of options. You could simplify this into something like:

<% if current_user.voted_up_on? @post %>
  <%= link_to "LIKE #{@post.get_upvotes.size}", like_post_path(@post), 
<% else %>
  <%= link_to "LIKE #{@post.get_upvotes.size}", like_post_path(@post), method: :post, class: "btn btn-outline-dark" %>
<% end %>

<% if current_user.voted_down_on? @post %>
  <%= link_to "DISLIKE #{@post.get_downvotes.size}", dislike_post_path(@post), method: :post, class: "btn btn-outline-danger" %>
<% else %>
  <%= link_to "DISLIKE #{@post.get_downvotes.size}", dislike_post_path(@post), method: :post, class: "btn btn-outline-dark" %>
<% end %>

However, I usually prefer something like

<% like_class    = current_user.voted_up_on?(@post)   ? 'btn-outline-primary' : 'btn-outline-dark' %>
<% dislike_class = current_user.voted_down_on?(@post) ? 'btn-outline-danger'  : 'btn-outline-dark' %>

<%= link_to "LIKE #{@post.get_upvotes.size}", like_post_path(@post), method: :post, class:like_class %>
<%= link_to "DISLIKE #{@post.get_downvotes.size}", dislike_post_path(@post), method: :post, class: dislike_class %>

A few things:

  1. I would probably put this into a helper method.

  2. Usually you would hide or at least disable the like button if the post has already been liked.

  3. You haven't shown your model's code but you need to be careful that you don't query the database twice, once for voted_up_on? and once for voted_down_on?. Since they are mutually exclusive you may want to have a single method that return the state (up, down or none) and use a case statement.

\$\endgroup\$
0
\$\begingroup\$

As you can easily identify from your code that link_to code for Like and Dislike are same for all conditions only the class value is changed so you can use below code it looks more clean:

<% like_class = current_user.voted_up_on? @post ? 'btn-outline-primary' : 'btn-outline-dark' %>
<% dislike_class = current_user.voted_down_on? @post ? 'btn-outline-danger' : 'btn-outline-dark' %>
<%= link_to "LIKE #{@post.get_upvotes.size}", like_post_path(@post), method: :post, class: "btn #{like_class}" %>
<%= link_to "DISLIKE #{@post.get_downvotes.size}", dislike_post_path(@post), method: :post, class: "btn #{dislike_class}" %>
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.