Reputation: 29
I am creating a shopping list app, each user has a list and each list has many items.
On the show page, I'm iterating over a users list and showing each item in the list and printing out the item name, description & a link to update the item.
The problem is, the update form always uses the first item in the each iteration instead of its assigned item.
I can have a list with 5 rows of items and the update link for each item will always populate with first item in the row.
I'm new to rails so any help with this would be appreciated!
Routes
Rails.application.routes.draw do
patch 'items/pick/:id', to: "items#pick", as: :pick
devise_for :users
root to: 'lists#index'
resources :lists do
resources :items
end
end
List controller
class ListsController < ApplicationController
def index
@lists = List.all
end
def show
@list = List.find(params[:id])
end
def new
@list = List.new
end
end
Item controller
class ItemsController < ApplicationController
def new
end
def create
@list = List.find(params[:list])
@item = Item.new(item_params)
@item.list_id = @list.id
@item.user_id = current_user.id
if @item.save!
redirect_to list_path(@list), notice: "Item added to list."
else
render :new, notice: "Something went wrong..."
end
end
def edit
end
def update
@item = Item.find(params[:id])
if @item.update(venue_params)
redirect_to venue_path(@venue)
else
render :edit
end
end
def destroy
@item = Item.find(params[:id])
@item.destroy
redirect_to list_path(params[:list_id])
end
def pick
item = Item.find(params[:id])
if item.buyer.nil?
item.buyer = current_user.id
else
item.buyer = nil
end
item.save!
redirect_to lists_path
end
def item_params
params.require(:item).permit(:item_name, :description, :link, :price)
end
end
Show page - update form rendered as the last item in the each loop
<div class="container">
<div class="row">
<div class="col-md-12 mt-5">
<h2>Hello <%= current_user.first_name %> 👋</h2>
<p>Welcome to Listy, the new home of your gift lists</p>
<h4 class="mb-3">Manage: <%= link_to "Family lists", lists_path %></h4>
<div class="card p-3 mb-3">
<p><%= @list.title %> ID: <%= @list.id %> </p>
<% @list.items.sort.each do |item| %>
<div class="list-flex">
<div class="item_name"><%= item.item_name %></div>
<div class="description-show-page"><%= item.description %></div>
<div class="link"><%= render "lists/partial/update_item", list: @list, item: item %></div>
</div>
<% end %>
</div>
<%= render "lists/partial/add_item" %>
</div>
</div>
</div>
Update partial
<a type="" class="gray" data-toggle="modal" data-target="#updateModal">
<i class="far fa-edit"></i>
</a>
<!-- Modal -->
<div class="modal fade" id="updateModal" tabindex="-1" role="dialog" aria-labelledby="exampleModalLabel" aria-hidden="true">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="exampleModalLabel">Update item</h5>
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
</div>
<div class="modal-body">
<%= simple_form_for [@list, item] do |f| %>
<h2> <%= item.id %></h2>
<%= hidden_field_tag 'list', @list.id %>
<%= f.input :item_name %>
<%= f.input :description %>
<%= f.input :link %>
<%= f.input :price %>
<%= f.submit "Add Item", class: "btn btn-outline-primary" %>
<% end %>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-outline-warning" data-dismiss="modal">Close</button>
</div>
</div>
</div>
</div>
Image of list on the show page, note the update links
Every update link renders the form using the first item in the list, 90 is the list ID
Upvotes: 0
Views: 346
Reputation: 1949
Seams a classic edit modal scenario
When you load the page, you render only one modal.
You have 3 records that mean, you need 3 modals
OR you can dynamically create a new modal like Rails: Edit record in Bootstrap modal
Upvotes: 1