I am currently doing simple CRUD. I already done in part of adding a new item, display all the items and now I want to view the specific item..
Question: How can I do that? Is my syntax correct?
Note: If yes, I am encountered erro " undefined local variable or method `item_showItem_path' for #<#:0xaf75068> Did you mean? items_addItem_path "
View
<h1>Welcome to my First CRUD!</h1>
<table border = "1" width="100%">
<tr>
<td>ID</td>
<td>Name</td>
<td>Description</td>
<td>Price</td>
<td>Created At</td>
<td>Updated At</td>
<td>Action</td>
</tr>
<% @items.each do |t| %>
<tr>
<td><%= t.id %></td>
<td><%= t.name %></td>
<td><%= t.description %></td>
<td><%= t.price %></td>
<td><%= t.created_at.strftime("%B, %d, %Y") %></td>
<td><%= t.updated_at %></td>
<td><%= link_to 'View ITEM', item_showItem_path%></td>
</tr>
<% end %>
</table>
<%= link_to 'Add ITEM', items_addItem_path %>
Controller
class ItemsController < ApplicationController
before_action :set_item, only: [:show,:edit,:destroy]
def index
@items = Item.all.order('created_at DESC')
end
def addItem
end
def create
@post = Item.new(post_params)
@post.save
redirect_to @items_path
end
def showItem
@post = Item.find(params[:id])
end
def show
end
private
def post_params
params.require(:item).permit(:name, :description, :price)
end
def set_post
@post = Item.find(params[:id])
end
end
My show view
<h1 class="name">
<%= @post.name%>
</h1>
<h1 class="description">
<%= @post.description%>
</h1><h1 class="date">
Submitted <%= time_ago_in_words(@post.created_at)%> Ago
</h1>
<%= link_to 'BACK', items_path %>
Routes
Rails.application.routes.draw do
root "items#index"
# URL Controller#method
get '/items/addItem' => 'items#addItem'
get '/items/' => 'items#index'
post '/items/create' => 'items#create'
get '/items/showItem/:id' => 'items#showItem'
end
Part of learning Rails is learning how to use the conventions to your advantage - at which you're failing since you're setup is more complex than it needs to be.
To create CRUD routes for a resource use resources
Rails.application.routes.draw do
root to: "items#index"
resources :items
end
This will create the following RESTful routes:
Prefix Verb URI Pattern Controller#Action
items GET /items(.:format) items#index
POST /items(.:format) items#create
new_item GET /items/new(.:format) items#new
edit_item GET /items/:id/edit(.:format) items#edit
item GET /items/:id(.:format) items#show
PATCH /items/:id(.:format) items#update
PUT /items/:id(.:format) items#update
DELETE /items/:id(.:format) items#destroy
Which means that we can create a link to item by:
<%= link_to item.name, item_path(item) %>
# Or
<%= link_to item.name, item %>
It also lets you do the rest of the CRUD operations on a item by changing the request method while the path remains the same:
<%= button_to 'Delete item', item_path(@item), method: :delete %>
# This is explicit just for the sake of the example
# normally you would just use `form_for(@item)`
<%= form_for(@item, path: item_path(@item), method: :patch) do |f| %>
<h1>Edit item</h1>
# ...
<% end %>
Note that there is no special path for create either. You create a new record by sending a POST
request to the collection path ( /items
).
This is what the simplest possible conventional CRUD controller for a classic web looks like:
class ItemsController < ApplicationController
before_action :set_item, only: [:show,:edit,:destroy]
# GET /items/new
def new
@item = Item.new
end
# POST /items
def create
@item = Item.new(post_params)
if @item.save
redirect_to @item, success: 'Item created'
else
render :new, error: 'Item was not valid'
end
end
# GET /items
def index
@items = Item.all.order('created_at DESC')
end
# GET /items/:id
# We don't even need to declare this since
# Rails will render the (items/show) view by convention.
#
# def show
# end
# GET /items/:id/edit
# We don't even need to declare this since
# Rails will render the (items/edit) view by convention.
#
# def edit
# end
# PUT|PATCH /items/:id
def update
if @item.update(item_params)
redirect_to @item, success: 'Item updated.'
else
render :edit
end
end
# DELETE /items/:id
def destroy
@item.destroy
redirect_to items_path, success: 'Item deleted.'
end
private
def item_params
params.require(:item).permit(:name, :description, :price)
end
def set_item
@item = Item.find(params[:id])
end
end
you will need to pass item id in your item_showItem_path
change this
<td><%= link_to 'View ITEM', item_showItem_path%></td>
to this
<td><%= link_to 'View ITEM', item_showItem_path(t) %></td>
or
<td><%= link_to 'View ITEM', item_showItem_path(t.id) %></td>
you can see in your routes, it is expecting :id
get '/items/showItem/:id' => 'items#showItem'
. Once you pass the object t
, rails will get id from that object.
SIDE NOTE:
your naming convention is not following ruby convention. normally in ruby we name methods using underscore.
eg showItem will be show_item
I would also rename variable t
to item
so it is easier to understand.
You already have show method in controller, so there is no need to define new method and route for showItem. you can just use show method.
You can also rename addItem
to def new
if you want to follow Rails convention.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.