【发布时间】:2017-05-22 20:48:59
【问题描述】:
我正在使用 Ruby on Rails 构建一个简单的表单来提交订单。
我的表单需要提交来自 3 个不同模型的信息:用户、catalog_item 和订单本身。
这是我的订单模型:
class Order < ApplicationRecord
after_initialize :default_values
validates :quantity, presence: true
belongs_to :user
belongs_to :catalog_item
validates :user_id, presence: true
validates :catalog_item_id, presence: true
accepts_nested_attributes_for :user
validates_associated :user
end
这是我的用户模型:
class User < ApplicationRecord
has_many :orders
end
这是我的控制器:
class OrdersController < ApplicationController
def checkout
@order = Order.new(catalog_item: CatalogItem.find(params[:catalog_item_id]), user: User.new)
end
def create
@order = Order.new(order_params)
if @order.save
# redirect_to confirmation_path
else
# redirect_to error_path
end
end
private
def user_params
[:name, :email, :phone_number]
end
def order_params
params.require(:order).permit(:id, :catalog_item_id, user_attributes: user_params)
end
end
这是我的视图形式:
<%= form_for @order do |order_form| %>
<%= order_form.hidden_field :catalog_item_id %>
<%= order_form.fields_for :user do |user_fields| %>
<%= user_fields.label :name %>
<%= user_fields.text_field :name %>
<%= user_fields.label :email %>
<%= user_fields.text_field :email %>
<%= user_fields.label :phone_number %>
<%= user_fields.text_field :phone_number %>
<% end %>
<%= order_form.submit %>
<% end %>
如果表单是 HTML:
<form class="new_order" id="new_order" action="/orders" accept-charset="UTF-8" method="post"><input name="utf8" type="hidden" value="✓"><input type="hidden" name="authenticity_token" value="+z8JfieTzJrNgsr99C4jwBtXqIrpNtiEGPdVi73qJrpiGPpjYzbLwUng+e+yp8nIS/TLODWVFQtZqS/45SUoJQ==">
<input type="hidden" value="1" name="order[catalog_item_id]" id="order_catalog_item_id">
<label for="order_user_attributes_name">Name</label>
<input type="text" name="order[user_attributes][name]" id="order_user_attributes_name">
<label for="order_user_attributes_email">Email</label>
<input type="text" name="order[user_attributes][email]" id="order_user_attributes_email">
<label for="order_user_attributes_phone_number">Phone number</label>
<input type="text" name="order[user_attributes][phone_number]" id="order_user_attributes_phone_number">
<input type="submit" name="commit" value="Create Order" data-disable-with="Create Order">
这是我的路线:
get 'checkout/:catalog_item_id', to: 'orders#checkout', as: 'checkout'
post 'orders', to: 'orders#create'
当我尝试将 @order 保存在操作 create 中时,我收到此错误:
#<ActiveModel::Errors:0x007fe95d58b698 @base=#<Order id: nil, quantity: 1, created_at: nil, updated_at: nil, user_id: nil, catalog_item_id: 1>, @messages={:user_id=>["can't be blank"]}, @details={:user_id=>[{:error=>:blank}]}>
但是,如果我这样做,它确实有效:
@catalog_item = CatalogItem.find(order_params[:catalog_item_id])
@user = User.new(order_params[:user_attributes])
@user.save
@order = Order.new(catalog_item: @catalog_item, user: @user)
这是我发布表单时在 HTTP 请求中发送的内容:
order[catalog_item_id]:1
order[user_attributes][name]:Ana
order[user_attributes][email]:ana@gmail.com
order[user_attributes][phone_number]:123123123
commit:Create Order
我是 RoR 的新手,我不明白为什么 order_params 没有用户,但它确实有 catalog_item_id。
任何帮助将不胜感激。谢谢!
【问题讨论】:
-
你发表了什么观点?记录 params 哈希,您将看到表单实际传递的内容。表单未收集到的方法所需的任何数据,您可以在隐藏字段中传递。
-
@margo 当我记录参数时,这就是我得到的
{"utf8"=>"✓", "authenticity_token"=>"9tXNW6m8fDha53/HGL1i+yTzDEDDsHbcx87KpqugI0dv8j5G7Rl7Y96FTNVeNIjzdFBv8h8Tu1OGkLDV828t2A==", "user"=><ActionController::Parameters {"name"=>"John", "email"=>"john@example.com", "phone_number"=>"123123123"} permitted: false>, "commit"=>"Create Order", "controller"=>"orders", "action"=>"create"} permitted: false>我从结帐视图get 'checkout/:catalog_item_id', to: 'orders#checkout', as: 'checkout'发布了表单。希望这是有道理的。 -
我对实际情况仍然有些困惑 - 一个订单只能有一件商品吗?
-
@max 是的,没错。这个想法是该应用程序将允许人们订购研讨会(catalog_items),但这是一个简单的工作流程,用户进入网站,选择研讨会并结帐。所以每个订单只有一个 catalog_item。也不需要登录。
-
是的,然后肯定将其设为嵌套路由。
标签: ruby-on-rails ruby forms ruby-on-rails-5