我的rails版本是5.0.5,我目前正在开发一个在线商店。我正在遵循敏捷Web开发的步骤(rails 5)。我已经按照相应的步骤,我可以创建新产品,编辑产品和删除产品,我被困在我要添加产品到购物车的阶段(“添加到购物车”按钮显示)当我点击“添加购物车“它给了我一个错误{无法找到带有id的产品} ..........这是错误的家伙。
ruby 2.4.1p111 (2017-03-22 revision 58053) [i386-mingw32]
C:\Users\COMPUTER>cd desktop
C:\Users\COMPUTER\Desktop>cd trial
C:\Users\COMPUTER\Desktop\trial>cd depot
C:\Users\COMPUTER\Desktop\trial\depot>rails s
=> Booting Puma
=> Rails 5.0.5 application starting in development on http://localhost:3000
=> Run `rails server -h` for more startup options
*** SIGUSR2 not implemented, signal based restart unavailable!
*** SIGUSR1 not implemented, signal based restart unavailable!
*** SIGHUP not implemented, signal based logs reopening unavailable!
Puma starting in single mode...
* Version 3.10.0 (ruby 2.4.1-p111), codename: Russell's Teapot
* Min threads: 5, max threads: 5
* Environment: development
* Listening on tcp://0.0.0.0:3000
Use Ctrl-C to stop
Started GET "/" for 127.0.0.1 at 2017-10-22 17:44:40 +0100
ActiveRecord::SchemaMigration Load (0.0ms) SELECT "schema_migrations".* FROM "schema_migrations"
Processing by StoreController#index as HTML
Rendering store/index.html.erb within layouts/application
Product Load (4.0ms) SELECT "products".* FROM "products" ORDER BY "products"."title" ASC
Rendered store/index.html.erb within layouts/application (620.0ms)
Completed 200 OK in 1888ms (Views: 1385.1ms | ActiveRecord: 20.0ms)
Started POST "/line_items" for 127.0.0.1 at 2017-10-22 17:46:14 +0100
Processing by LineItemsController#create as HTML
Parameters: {"authenticity_token"=>"tysgjA3w3dfMA1ACBRWeigDDnDM9WDiwBDKotUwmXVVxVy0+msnR4gmkB3QV8qU8dKdLdnb5yEOS5FmdUs7LyQ=="}
Cart Load (4.0ms) SELECT "carts".* FROM "carts" WHERE "carts"."id" = ? LIMIT ? [["id", nil], ["LIMIT", 1]]
(4.0ms) begin transaction
SQL (48.0ms) INSERT INTO "carts" ("created_at", "updated_at") VALUES (?, ?) [["created_at", "2017-10-22 16:46:15.531901"], ["updated_at", "2017-10-22 16:46:15.531901"]]
(108.0ms) commit transaction
Product Load (4.0ms) SELECT "products".* FROM "products" WHERE "products"."id" = ? LIMIT ? [["id", nil], ["LIMIT", 1]]
Completed 404 Not Found in 644ms (ActiveRecord: 180.0ms)
ActiveRecord::RecordNotFound (Couldn't find Product with 'id'=):
app/controllers/line_items_controller.rb:29:in `create'
Rendering C:/Ruby24/lib/ruby/gems/2.4.0/gems/actionpack-5.0.5/lib/action_dispatch/middleware/templates/rescues/diagnostics.html.erb within rescues/layout
Rendering C:/Ruby24/lib/ruby/gems/2.4.0/gems/actionpack-5.0.5/lib/action_dispatch/middleware/templates/rescues/_source.html.erb
Rendered C:/Ruby24/lib/ruby/gems/2.4.0/gems/actionpack-5.0.5/lib/action_dispatch/middleware/templates/rescues/_source.html.erb (52.0ms)
Rendering C:/Ruby24/lib/ruby/gems/2.4.0/gems/actionpack-5.0.5/lib/action_dispatch/middleware/templates/rescues/_trace.html.erb
Rendered C:/Ruby24/lib/ruby/gems/2.4.0/gems/actionpack-5.0.5/lib/action_dispatch/middleware/templates/rescues/_trace.html.erb (24.0ms)
Rendering C:/Ruby24/lib/ruby/gems/2.4.0/gems/actionpack-5.0.5/lib/action_dispatch/middleware/templates/rescues/_request_and_response.html.erb
Rendered C:/Ruby24/lib/ruby/gems/2.4.0/gems/actionpack-5.0.5/lib/action_dispatch/middleware/templates/rescues/_request_and_response.html.erb (16.0ms)
Rendered C:/Ruby24/lib/ruby/gems/2.4.0/gems/actionpack-5.0.5/lib/action_dispatch/middleware/templates/rescues/diagnostics.html.erb within rescues/layout (8928.0ms)
以下是商店(显示产品的默认主页)视图文件.....
<p id="notice"><%= notice %></p>
<h1>Your Pragmatic Catalog</h1>
<% cache @products do %>
<% @products.each do |product| %>
<% cache @product do %>
<div class="entry">
<h3><%= product.title %></h3>
<%= image_tag(product.image_url) %>
<%= sanitize(product.description) %>
<div class="price_line">
<span class="price"><%= number_to_currency (product.price) %></span>
<%= button_to 'Add to Cart' , line_items_path %>
</div>
</div>
<% end %>
<% end %>
<% end %>
以下是路线......
Rails.application.routes.draw do
resources :line_items
resources :carts
root 'store#index', as: 'store_index'
resources :products
# For details on the DSL available within this file, see http://guides.rubyonrails.org/routing.html
end
以下是产品型号......
class Product < ApplicationRecord
validates :title, :description, :image_url, presence: true
validates :price, numericality: {greater_than_or_equal_to: 0.01}
validates :title, uniqueness: true
validates :image_url, allow_blank: true, format: {
with: %r{\.(gif|jpg|png)\Z}i,
message: 'must be a URL for GIF, JPG or PNG image.'
}
has_many :line_items
before_destroy :ensure_not_referenced_by_any_line_item
#...
private
# ensure that there are no line items referencing this product
def ensure_not_referenced_by_any_line_item
unless line_items.empty?
errors.add(:base, 'Line Items present')
throw :abort
end
end
end
下面是推车型号....
class Cart < ApplicationRecord
has_many :line_items, dependent: :destroy
end
def add_product (lineitem, product_id)
current_item = line_items.find_by(product_id: product.id)
if current_item
current_item.quantity += 1
else
current_item = line_items.build(product_id: product.id)
end
current_item
end
订单项型号....
class LineItem < ApplicationRecord
belongs_to :product
belongs_to :cart
end
application_record.rb ........
class ApplicationRecord < ActiveRecord::Base
self.abstract_class = true
end
推车控制器....
class CartsController < ApplicationController
before_action :set_cart, only: [:show, :edit, :update, :destroy]
# GET /carts
# GET /carts.json
def index
@carts = Cart.all
end
# GET /carts/1
# GET /carts/1.json
def show
end
# GET /carts/new
def new
@cart = Cart.new
end
# GET /carts/1/edit
def edit
end
# POST /carts
# POST /carts.json
def create
@cart = Cart.new(cart_params)
respond_to do |format|
if @cart.save
format.html { redirect_to @cart, notice: 'Cart was successfully created.' }
format.json { render :show, status: :created, location: @cart }
else
format.html { render :new }
format.json { render json: @cart.errors, status: :unprocessable_entity }
end
end
end
# PATCH/PUT /carts/1
# PATCH/PUT /carts/1.json
def update
respond_to do |format|
if @cart.update(cart_params)
format.html { redirect_to @cart, notice: 'Cart was successfully updated.' }
format.json { render :show, status: :ok, location: @cart }
else
format.html { render :edit }
format.json { render json: @cart.errors, status: :unprocessable_entity }
end
end
end
# DELETE /carts/1
# DELETE /carts/1.json
def destroy
@cart.destroy
respond_to do |format|
format.html { redirect_to carts_url, notice: 'Cart was successfully destroyed.' }
format.json { head :no_content }
end
end
private
# Use callbacks to share common setup or constraints between actions.
def set_cart
@cart = Cart.find(params[:id])
end
# Never trust parameters from the scary internet, only allow the white list through.
def cart_params
params.fetch(:cart, {})
end
end
application controller.....
class ApplicationController < ActionController::Base
protect_from_forgery with: :exception
end
订单项控制器....
class LineItemsController < ApplicationController
include CurrentCart
before_action :set_cart, only: [:create]
before_action :set_line_item, only: [:show, :edit, :update, :destroy]
# GET /line_items
# GET /line_items.json
def index
@line_items = LineItem.all
end
# GET /line_items/1
# GET /line_items/1.json
def show
end
# GET /line_items/new
def new
@line_item = LineItem.new
end
# GET /line_items/1/edit
def edit
end
# POST /line_items
# POST /line_items.json
def create
product = Product.find (params[:product_id])
@line_item = @cart.line_items.build(product: product)
respond_to do |format|
if @line_item.save
format.html { redirect_to @line_item.cart, notice: 'Line item was successfully created.' }
format.json { render :show, status: :created, location: @line_item }
else
format.html { render :new }
format.json { render json: @line_item.errors, status: :unprocessable_entity }
end
end
end
# PATCH/PUT /line_items/1
# PATCH/PUT /line_items/1.json
def update
respond_to do |format|
if @line_item.update(line_item_params)
format.html { redirect_to @line_item, notice: 'Line item was successfully updated.' }
format.json { render :show, status: :ok, location: @line_item }
else
format.html { render :edit }
format.json { render json: @line_item.errors, status: :unprocessable_entity }
end
end
end
# DELETE /line_items/1
# DELETE /line_items/1.json
def destroy
@line_item.destroy
respond_to do |format|
format.html { redirect_to line_items_url, notice: 'Line item was successfully destroyed.' }
format.json { head :no_content }
end
end
private
# Use callbacks to share common setup or constraints between actions.
def set_line_item
@line_item = LineItem.find(params[:id])
end
# Never trust parameters from the scary internet, only allow the white list through.
def line_item_params
params.require(:line_item).permit(:product_id, :cart_id)
end
end
产品控制器......
class ProductsController < ApplicationController
before_action :set_product, only: [:show, :edit, :update, :destroy]
# GET /products
# GET /products.json
def index
@products = Product.all
end
# GET /products/1
# GET /products/1.json
def show
end
# GET /products/new
def new
@product = Product.new
end
# GET /products/1/edit
def edit
end
# POST /products
# POST /products.json
def create
@product = Product.new(product_params)
respond_to do |format|
if @product.save
format.html { redirect_to @product, notice: 'Product was successfully created.' }
format.json { render :show, status: :created, location: @product }
else
format.html { render :new }
format.json { render json: @product.errors, status: :unprocessable_entity }
end
end
end
# PATCH/PUT /products/1
# PATCH/PUT /products/1.json
def update
respond_to do |format|
if @product.update(product_params)
format.html { redirect_to @product, notice: 'Product was successfully updated.' }
format.json { render :show, status: :ok, location: @product }
else
format.html { render :edit }
format.json { render json: @product.errors, status: :unprocessable_entity }
end
end
end
# DELETE /products/1
# DELETE /products/1.json
def destroy
@product.destroy
respond_to do |format|
format.html { redirect_to products_url, notice: 'Product was successfully destroyed.' }
format.json { head :no_content }
end
end
private
# Use callbacks to share common setup or constraints between actions.
def set_product
@product = Product.find(params[:id])
end
# Never trust parameters from the scary internet, only allow the white list through.
def product_params
params.require(:product).permit(:title, :description, :image_url, :price)
end
end
商店控制器.....
class StoreController < ApplicationController
def index
@products = Product.order(:title)
end
end
你的错误是ActiveRecord::RecordNotFound (Couldn't find Product with 'id'=):
。这意味着控制器不知道您要将哪个产品添加到购物车。这可以通过在product_id
的参数中添加POST
来完成。
在你看来:
<%= button_to 'Add to Cart' , line_items_path %>
line_items_path
可能不正确。你可能想要line_item_path(product_id: product.id)
。这会将产品的ID添加到请求中,并在控制器尝试在此处查找记录时使其可用:
product = Product.find (params[:product_id])
在视图中,您必须按照Daniel Westendorf的建议发送正确的product_id
<%= button_to 'Add to Cart' , line_items_path(product_id: product.id) %>
所以,这样当你在LineItem
的new
方法中创建一个新的LinesItemController
时,你有它的参数
def new
@line_item = LineItem.new(params[:product_id])
end
要使用调试模式,您可以使用byebug,您可以使用此step_by_step installation指南。 pry是另一种选择。