Reputation: 1125
I have a tree of products in Rails 3.2 and would like to have an add/remove feature so that users can add new children products or remove existing children for a product. I use the ancestry gem to generate the tree, for a Product 1 it might look like this:
Product 1
add | remove
Product 2
add | remove
Product 3
add | remove
In a partial _product.html.erb I have added Add and Remove links, which works for the add feature, but I cannot get the remove link to work:
<span><%= product.name.capitalize %></span>
<%= link_to "Add", new_product_path(parent_id: product) %> |
<%= link_to "Remove", {parent_id: nil}, method: :update %>
I would like to update the parent_id to nil for the product to be removed when "Remove" is clicked, but the above link_to doesn't seem to be working. I get an: No route matches [POST] "/products/1/edit" routing error. In my product_controller I have:
def update
if @product.update_attributes(params[:product])
flash[:success] = "Product updated"
redirect_to @product
else
render 'edit'
end
end
What am I doing wrong?
Edit:
I tried to use method: put
instead:
<%= link_to "Remove", {parent_id: nil}, method: :put %>
then I get a No route matches [PUT] "/products/1/edit"
error instead when clicking on the link.
I can now change/remove the parent using a form, not at all what I want but anyway:
<%= form_for @product do |f| %>
<%= f.label :parent_id %>
<%= f.text_field :parent_id %>
<%= f.submit "Update", class: "btn" %>
<% end %>
Would it be possible to automatically pass the parent_id: nil into the form so that when you hit Update, it sets the parent_id: nil (not having a text field just a button)?
Upvotes: 3
Views: 6731
Reputation: 1125
I finally got it to work thanks to @krichard answer together with @froderiks comment, by setting the path to /products/id and passing parent_id: nil
using method: :put
:
<%= link_to "Remove", "/products/#{product.id}?product%5Bparent_id%5D=", method: :put %>
The same effect can be achieved using form_for and a hidden_field (Passing a fixed value to a field using a button/link):
<%= form_for product do |f| %>
<%= f.hidden_field :parent_id, value: nil %>
<%= f.submit "Remove", class: "btn" %>
<% end %>
If a hidden_field_tag is used instead of f.hidden_field, :parent_id must be picked up in the controller (thanks @froderik):
<%= form_for product do |f| %>
<%= hidden_field_tag :parent_id, nil %>
<%= f.submit "Remove", class: "btn" %>
<% end %>
products_controller.rb
def update
@product.parent_id = params[:parent_id]
...
end
Upvotes: 2