Rails - 似乎无法将参数传递给方法

时间:2016-01-12 13:58:52

标签: ruby-on-rails

我正在尝试设置一个简单的购物车。我希望能够点击添加'在记录上然后将该项目添加到具有记录/行的ID的购物车中

<% @documents.each do |document| %>
  <td><%= link_to "add",  add_to_cart_path(8), :method => :post %></td>
<% end %>

我将add_to_cart_path(8)作为故障排除。我真的希望它是add_to_cart(document.id)但是,无论哪种方式,当前的doc id参数都没有传递给新项目记录的创建。

我的路线是

post '/add_to_cart/:doc_id' => 'carts#add_to_cart', :as => 'add_to_cart'

推车控制器

def add_to_cart
  $current_doc_id = doc_id
  current_cart.add_item(:doc_id)
  redirect_to carts_path(current_cart.id)
end

我的购物车模型

def add_item(document_id)
  @line_item = Item.create(:document_id => document_id, :cart_id => $cart_number)
  if @line_item.save
    #  flash[:success] = "item added!"
  else
    #  flash[:fail] = "!"
  end
end

当我查看项目表时,正在创建记录并正确填充购物车ID。但是,document_id字段为&#39; null&#39;。

1 个答案:

答案 0 :(得分:0)

我知道你有答案,但我想稍微清理你的代码......

#config/routes.rb
resources :cart, only: [] do
   collection do
     post "add/:document_id", to: :create        #-> url.com/cart/add/:document_id
     delete "remove/:document_id", to: :destroy  #-> url.com/cart/remove/:document_id
   end
end

#app/controllers/cart_controller.rb
class CartController < ApplicationController
   before_action :set_document

   def create
     current_cart.line_items << @document
     redirect_to carts_path current_cart.id
   end

   def destroy
     current_cart.line_items.delete @document
     redirect_to carts_path current_cart.id
   end

   private

   def set_document
     @document = Document.find params[:document_id]
   end

end

这将允许您使用:

<%= link_to "Add to Cart", carts_add_path(@document), method: :post %>
<%= link_to "Remove from Cart", carts_remove_path(@document), method: :delete %>

您有一个基本的antipattern,因为您在Cart模型中使用了基于请求的逻辑。模型应该只用于数据驱动的逻辑;请求逻辑都需要保存在您的控制器中:

if @line_item.save
    #  flash[:success] = "item added!"
  else
    #  flash[:fail] = "!"
end

...如果您依赖它来形成回复,则需要在您的控制器中。

我们之前已经设置过购物车(使用session model)。您可能会受益于我们使用的代码。它与你的根本不同之处在于它将购物车保存在一个会话cookie中,而不是将数据保存在模型中:

enter image description here

#config/routes.rb
resources :cart do 
   collection do
       post   'cart/add/:id', to: 'cart#add', as: :cart_add
       delete 'cart/remove(/:id(/:all))', to: 'cart#delete', as: :cart_delete
   end
end

#app/controllers/cart_controller.rb
class CartController < ApplicationController
    include ApplicationHelper

    #Index
    def index
        @items = cart_session.cart_contents
    end

    #Add
    def add
        session[:cart] ||={}
        products = session[:cart][:products]

        #If exists, add new, else create new variable
        if (products && products != {})
            session[:cart][:products] << params[:id]
        else
            session[:cart][:products] = Array(params[:id])
        end

        #Handle the request
        respond_to do |format|
            format.json { render json: cart_session.build_json }
            format.html { redirect_to cart_index_path }
        end
    end

    #Delete
    def delete
        session[:cart] ||={}
        products = session[:cart][:products]
        id = params[:id]
        all = params[:all]

        #Is ID present?
        unless id.blank?
            unless all.blank?
                products.delete(params['id'])
            else
                products.delete_at(products.index(id) || products.length)
            end
        else
            products.delete
        end

        #Handle the request
        respond_to do |format|
            format.json { render json: cart_session.build_json }
            format.html { redirect_to cart_index_path }
        end
    end

end

然后显示购物车:

#app/views/cart/index.html.erb
<% @items.each do |item| %>
   <%= item.name %>
<% end %>

如果不合适,我会删除,我认为这会给你一些观点。