Ruby Rails中destroy.js报500错误及Nil类问题咨询
Hey there! Let's break down this 500 error issue with your Wishitem destroy action. From what you've shared, it’s super odd that the destroy works (you see changes after a refresh) but throws a nil class id error during the AJAX request—let’s figure out why.
First, Let’s Target the Most Likely Culprits
1. Your destroy Action in WishitemsController Is Missing Critical Instance Variables
When you use AJAX for destroy, your destroy.js.erb template probably needs access to the associated Product (since you’re on a product detail page) to update the view correctly. If you’re not setting that variable, or if @wishitem is coming up nil, you’ll hit that 500 error.
Check your controller code—here’s a fix that should cover both cases:
def destroy # Use find_by to avoid hard exceptions if the wishitem doesn't exist @wishitem = Wishitem.find_by(id: params[:id]) if @wishitem # Grab the associated product for the JS template to use @product = @wishitem.product @wishitem.destroy else # Handle missing wishitem gracefully respond_to do |format| format.js { render js: "alert('Could not find that wishlist item!');" } format.html { redirect_to products_path, alert: "Wishlist item not found." } end return end respond_to do |format| format.js # This will render destroy.js.erb format.html { redirect_to @product, notice: "Removed from wishlist." } end end
2. Your destroy.js.erb Is Trying to Access a Nil Object
If your JS template references @wishitem.id or expects a product variable that’s not set, it’ll throw that nil error. For example, if your template looks like this (and @product isn’t set in the controller):
# Bad: If @product is nil, this will fail $('#wishlist-toggle').html('<%= j render partial: "products/add_to_list", locals: { product: @product } %>');
With the fixed controller above, you can safely use @product to refresh the toggle button:
# Good: Uses the @product we set in the controller $('#wishlist-toggle').html('<%= j render partial: "products/add_to_list", locals: { product: @product } %>'); # Or if you need to remove a specific wishitem element: $('#wishitem-<%= params[:id] %>').remove();
3. Your Destroy Link Isn’t Passing the Correct wishitem_id
Double-check the _remove_from_list partial to make sure the link is generating the right URL with the wishitem’s ID:
<%= link_to "Remove from Wishlist", wishitem_path(wishitem), method: :delete, remote: true %>
If wishitem is nil here (e.g., you’re not passing the correct local variable to the partial), the link will have an invalid ID, leading to Wishitem.find failing in the controller.
Quick Recap of the Fixes
- Ensure your
destroyaction sets@product(for the view) and handles missing wishitems gracefully. - Update
destroy.js.erbto use variables that are guaranteed to exist (like@productorparams[:id]). - Verify your destroy link is passing a valid wishitem ID.
Once you tweak these, the AJAX destroy should work smoothly without throwing that 500 error—just like your create action does!
内容的提问来源于stack exchange,提问作者roshiend

