新手问题 undefined method `add_product' for 12:Fixnum

torubylist · 2015年11月12日 · 最后由 JIAZHEN 回复于 2015年12月11日 · 2699 次阅读

大家好。我的目标就是添加一条记录到购物车。在执行的过程中找不到 add_product 方法。其实就是@cart出了问题。@cart是 current_cart。整个逻辑我没看出来问题。求解答。谢谢。 error: NoMethodError in LineItemsController#create undefined method `add_product' for 12:Fixnum

代码如下。 controller: app/controllers/application_controller.rb

class ApplicationController < ActionController::Base
  # Prevent CSRF attacks by raising an exception.
  # For APIs, you may want to use :null_session instead.
  protect_from_forgery with: :exception
  private
    def current_cart
      Cart.find(session[:cart_id])
    rescue ActiveRecord::RecordNotFound
      cart = Cart.create
      session[:cart_id]  = cart.id
    end
end

app/controllers/line_items_controller.rb

class LineItemsController < ApplicationController
  before_action :set_line_item, only: [:show, :edit, :update, :destroy]

  def create
    @cart      = current_cart
    product    = Product.find(params[:product_id])
    @line_item = @cart.add_product(product.id)

    respond_to do |format|
      if @line_item.save
        format.html { redirect_to(@line_item.cart) }
        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
end

model

class Cart < ActiveRecord::Base
  has_many :line_items, :dependent => :destroy
  def add_product(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
  def total_price
    line_items.to_a.sum{ |item| item.total_price }
  end
end

view

<h1>Your Pragmatic Catalog</h1>
<% @products.each do |product| %>
  <div class="entry">
    <%= link_to image_tag(product.image_url),line_items_path(:product_id => product),
                                            method: :post %><br />
    <h3><%= product.title %></h3>
    <%= sanitize(product.description) %>
    <div class="price_line">
      <span class="price"><%= number_to_currency(product.price) %></span>
      <%= button_to 'Add to Cart',line_items_path(:product_id => product )%>
    </div>
  </div>
<% end %>

改一下 current_cart 方法:

def current_cart
  Cart.find(session[:cart_id])
rescue ActiveRecord::RecordNotFound
  cart = Cart.create
  session[:cart_id]  = cart.id
  cart
end

#1 楼 @santochancf 为啥啊?请问能详细解答下么?多谢啊。

#1 楼 @santochancf ruby 里面方法返回值的问题么。看来 ruby 还得多学下。

#3 楼 @torubylist 默认最后一行为返回值,你的代码返回了cart .id

Do not use exception as the control flow ...

def current_cart
  cart = Cart.find(session[:cart_id]) || Cart.create
  session[:cart_id]  ||= cart.id
  cart
end

#5 楼 @JIAZHEN 不应该用 find_or_create 家族? 直接用 find 会出exception,用||没用吧?

@msg7086 you're right. It will throw error if not found. (Apologise that I can't type CN on this machine...)

Release Load (6.1ms)  SELECT  `releases`.* FROM `releases` WHERE `releases`.`id` = 99 LIMIT 1
ActiveRecord::RecordNotFound: Couldn't find Release with 'id'=99
需要 登录 后方可回复, 如果你还没有账号请 注册新账号