【问题标题】:cant add to cart rails 5无法添加到购物车导轨 5
【发布时间】:2017-12-31 07:09:53
【问题描述】:

我的 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

【问题讨论】:

  • 为什么不在create中使用强参数line_item_params ?或者使用断点byebugpry 来查看参数中收到的内容。
  • 我是新手,请告诉我如何使用 byebug 或 pry 或如何使用 line_ items_params 来解决此问题。谢谢西尔维 M

标签: ruby-on-rails ruby-on-rails-5


【解决方案1】:

您的错误是ActiveRecord::RecordNotFound (Couldn't find Product with 'id'=):。这意味着控制器不知道您要添加到购物车的产品。这可以通过在 POST 的参数中添加 product_id 来完成。

在你看来:

<%= 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 我刚刚做了你说我应该做的事,但我得到了一个错误.......这是错误...... .
【解决方案2】:

在视图中,您必须按照Daniel Westendorf 的建议发送正确的product_id

<%= button_to 'Add to Cart' , line_items_path(product_id: product.id) %>

这样,当你在LinesItemControllernew 方法中创建一个新的LineItem 时,你就有了它的参数

def new
  @line_item = LineItem.new(params[:product_id])
end

要使用调试模式,您可以使用byebug,也可以使用此step_by_step installation 指南。 pry 是另一种选择。

【讨论】:

    猜你喜欢
    • 2020-05-30
    • 1970-01-01
    • 2021-12-20
    • 1970-01-01
    • 1970-01-01
    • 2015-10-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多