我正在使用Rails和javascript构建一个简单的单页购物车。
我有一个包含我的~8个产品的数据库,这就是我的购物页面的样子:
<%= form_for @order do |f| %>
<% @product.each do |product| %>
<%= f.number_field(:product, class: "order-list", name: "#{product.name}", data: {price: "#{product.price}"}, value: 0, in: 0..5) %>
<% end %>
<%= f.submit "Continue" %>
<% end %>
当我点击提交时,我收到了这个参数
{"utf8"=>"✓", "authenticity_token"=>"mkFBHjgsGZ/dwmQ+Ct6HzafLNwDQlVXOVTdsO97IUUrg7PV9HlpdzJa9Iy03I85t0Nx7dUBKuqZfuGmE700fFQ==", "NameofProduct1"=>"0", "NameofProduct2"=>"0", "NameofProduct3"=>"2", "NameofProduct4"=>"1", "NameofProduct5"=>"0", "commit"=>"Continue", "controller"=>"orders", "action"=>"create"}
使用输入数字字段处理类似购物车的最佳方法是什么?如何处理params?在服务器端,我应该循环所有产品,找到名称,将其与数量合并并保存到数据库?将每个产品作为对象存储在数组中是一个好主意吗?
另外如何处理模型:传递它只是值大于0的参数?因为我有一个像“NameofProductxxxx”的访问权限。
将来我想干它 - 如果我要添加产品我不想改变模型或参数。
最后一页看起来像这样(对本地语言道歉): 谢谢
答案 0 :(得分:3)
首先,您需要在Order和Product之间建立适当的多对多关系。
screen
您可以使用以下命令生成LineItem模型:
class Order < ActiveRecord::Base
has_many :line_items
has_many :products, through: :line_items
accepts_nested_attributes_for :line_items
end
# as in a row on a order form.
class LineItem < ActiveRecord::Base
belongs_to :order
belongs_to :product
end
class Product < ActiveRecord::Base
belongs_to :order
belongs_to :product
has_many :orders, through: :line_items
end
如果必须处理小数值,您可能希望对rails g model LineItem order:belongs_to product:belongs_to quantity:integer
使用双精度类型。
然后,您将使用fields_for
创建字段,以便在订单的同时创建/更新关联的订单项。 quantity
遍历关联的记录并创建“范围”输入:
fields_for
请注意,您不必对产品ID使用select - 它也可以是隐藏字段。 提交表单应该会产生如下所示的params哈希:
<%= form_for(@order) do |f| %>
<%= f.fields_for(:line_items) do |ff| %>
<%= ff.collection_select(:product_id, Product.all, :id, :name) %>
<%= ff.label(:quantity) %>
<%= ff.number_field(:quantity) %>
<% end %>
<% end %>
由于我们的订单模型order: {
line_items_attributes: [
{
product_id: 6,
quantity: 4
}
]
}
,您会将这些参数列入白名单:
accepts_nested_attributes_for :line_items
显示每行成本是您需要解决的下一个问题。
通常你会做类似的事情:
class OrdersController < ApplicationController
def new
@order = Order.new
@order.line_items.new # seeds form with an empty item.
end
def create
@order = Order.create(order_params)
respond_with(@order)
end
def update
@order = Order.find(params[:id])
@order.update(order_params)
respond_with(@order)
end
private
def order_params
params.require(:order).permit(line_items_attributes: [:product_id, :quantity])
end
end
class LineItem < ActiveRecord::Base
belongs_to :order
belongs_to :product
def total
product.price * quantity
end
end
但是,如果您想在用户更改数量或项目时更新总数,则需要实施AJAX调用,这是一个独立的竞争问题或教程。