Rails ajax create new record

Viewed 110

I have a list of items with a "like" button on each item. I want to be able to save that user's like inline from the list without reloading the page.

index.html.erb

<% @items.each do |i| %>
  <%= link_to(i) do %>
    <div class="item" style="background-image: url('<%= i.image.url %>')">
      <div class="itemgradient">
        <div class="metadata">
          <div class="name"><%= i.name %></div>
        </div>
        <div class="actions">
          <div class="heart like">
            <div class="glyf">
            </div>
          </div>
          <div class="price">
            <%= number_to_currency(i.price).gsub(/\.00$/, "")%>
          </div>
        </div> 
      </div>
    </div>
  <% end %>
 <% end %>


<script type="text/javascript">
  $("div.like").on("click", function() {
    $.ajax("/restaurants/likeitem");
    $(this).removeClass("like");
    $(this).addClass("unlike");
  });
</script>

restaurants_controller.erb

def likeitem
    if current_user
      l = LikedItem.new(:user_id => current_user)      
      l.save!
    else
      # if not logged in, make them sign up
    end
  end

models/likeditem.rb

class LikedItem < ApplicationRecord
    belongs_to :user
    belongs_to :item
end

However, every time I'm clicking the like button, I'm getting this 500 error:

Completed 422 Unprocessable Entity in 59ms (ActiveRecord: 0.4ms | Allocations: 8492)

ActiveRecord::RecordInvalid (Validation failed: User must exist, Item must exist):

How do I make sure I'm passing through the right item ID to that ajax put?

1 Answers

In your ajax call you don't pass any item id to controller, to fix that you can do this:

1- Add data-attribute that contains item's id to div.like

<div class="heart like" data-id="<%= i.id %>">
  <div class="glyf"></div>
</div>

2- Add item's id to ajax call

<script type="text/javascript">
  $("div.like").on("click", function() {
    var $this = $(this) 
    $.ajax({
      url: "/restaurants/likeitem", 
      data: {
        item_id: $this.data("id")
      }
    })
    $(this).removeClass("like");
    $(this).addClass("unlike");
  });
</script>


After that you can access item_id in controller:

def likeitem
  if current_user
    l = LikedItem.new(:item_id => params[:item_id], :user_id => current_user)      
    l.save!
  else
    # if not logged in, make them sign up
  end
end
Related