User flow:
The extra thing is that the list of items rendered in the view is sortable by Ransack gem. So the question is, in the snippet of form code below, what variable needs to be called by the update
action if @inventories
is a variable required by Ransack to make the list sortable in the action 'new'?
@inventories.each do |inventory|
form_for inventory do |f|
f.text_field ...
Right now the form and everything loads correctly, but the description that's submitted doesn't get PATCHed anywhere.
FOR MORE CONTEXT AND FULL CODE:
Controller code:
def new
#initializes the parent object needed to create the initial inventory of items
@signup_parent = Signup.find_by_email(session[:signup_email])
#required by Ransack gem to display results
@q = @signup_parent.inventories.ransack(params[:q])
@inventories = @q.result.includes(:signup)
end
def create
@signup_parent = Signup.find_by_email(session[:signup_email])
items_to_be_saved = []
#at some point array is populated with list of items user selects in form
@signup_parent.inventories.create items_to_be_saved
end
def update
#since the form_fors are generated by an each do that simultaneously creates forms and generates list of existing items, I figured I'd need to follow the same convention as the 'new' action
@signup_parent = Signup.find_by_email(session[:signup_email])
@q = @signup_parent.inventories.ransack(params[:q])
@inventories = @q.result.includes(:signup)
redirect_to :action => 'new'
end
View code:
<% if @signup_parent.inventories.count > 0 %>
<div class="table-responsive">
<table class="table table-condensed table-hover">
<thead>
<tr>
<th><%= sort_link(@q, :item_name, "Item") %></th>
<th>Description</th>
<th colspan="5"></th>
</tr>
</thead>
<tbody>
<% @inventories.each do |inventory| %>
<tr>
<td><%= inventory.item_name %></td>
<td>
<% if inventory.description.blank? %>
<%= form_for inventory, url: {action: 'update'}, :html => {:class => "form-inline"} do |f| %>
<div class="form-group col-xs-9">
<%= f.text_field :description, class: "form-control", placeholder: "Add description" %>
</div>
<div class="form-group col-xs-3">
<%= f.submit "Update", class: "btn btn-default btn-large btn-block" %>
</div>
<% end %>
<% else %>
<%= inventory.description %>
<% end %>
</td>
<td>
<% if inventory.description.present? %>
<%= button_to %>
<!-- no clue, separate question (but feel free to solve!) need this button to, 1) ideal solution: "reactivate" form with the description so that users can edit what they've put in, 2) hacky solution: delete the description entirely so that users will have to re-enter it in the form that renders once description is blank again -->
<% end %>
<%= button_to 'Remove', inventory, method: :delete, class: "btn btn-default btn-large btn-block" %>
</td>
</tr>
<% end %>
</tbody>
</table>
</div>
<% else %>
<!-- if they don't have any items, they see the create form -->
<% end %>
Routes
resources :inventories, only: [:new, :create, :destroy]
patch 'inventories', to: 'inventories#update'
In case it's helpful to anyone else:
Routes code
resources :inventories, only: [:new, :create, :destroy]
patch 'inventories/:id/edit', to: 'inventories#update', as: 'edit_inventory'
patch 'inventories/:id/destroy_description', to: 'inventories#destroy_description', as: 'destroy_description'
Controller code
def update
@inventory = Inventory.find(params[:id])
@inventory.update_attributes(inventory_update_params)
if request.referer.include? 'admin'
redirect_to :action => 'index'
else
redirect_to :action => 'new'
end
end
def destroy_description
@inventory = Inventory.find(params[:id])
@inventory.update_attributes(description: "")
if request.referer.include? 'admin'
redirect_to :action => 'index'
else
redirect_to :action => 'new'
end
end
View code
<tbody>
<% @inventories.each do |inventory| %>
<tr>
<td><%= inventory.signup.email %></td>
<td><%= inventory.item_name %></td>
<td>
<% if inventory.description.blank? %>
<%= form_for inventory, url: edit_inventory_path(inventory), method: :patch, :html => {:class => "form-inline", :autocomplete => "off"} do |f| %>
<div class="form-group col-xs-10" style="padding:1px;">
<%= f.text_field :description, class: "form-control", placeholder: "Add a link or description" %>
</div>
<div class="form-group col-xs-2" style="padding:1px;">
<%= f.submit "Add", class: "btn btn-default btn-default btn-block" %>
</div>
<% end %>
<% else %>
<%= inventory.description %>
<% end %>
</td>
<td>
<% if inventory.description.present? %>
<div class="col-xs-6" style="padding:1px; ">
<%= button_to 'New description', destroy_description_path(inventory), method: :patch, class: "btn btn-default btn-default btn-block" %>
</div>
<% end %>
<div class="col-xs-6" style="padding:1px; ">
<%= button_to 'Remove item', inventory, method: :delete, class: "btn btn-default btn-default btn-block", data: { confirm: 'Once removed, borrowers will no longer be able to see you have this item. To remove an item temporarily (i.e., for a personal trip), please notify us via email' } %>
</div>
</td>
</tr>
<% end %>
</tbody>