我正在尝试在同一页面上创建一个包含送货地址和帐单地址的地址表。 当用户准备好结帐时,我希望送货地址表和账单地址都显示在同一页面上。如果账单地址与送货地址相同,则仅应将记录插入地址表,如果必须插入不同的两条记录,当然必须在订单表 shipping_address_id、billing_address_id 中进行更新。
只有一个地址模型,如何用一个提交按钮实现两个表单。 下面是我的地址和订单模型
我需要一些帮助来安装 Controller ,我也在尝试为每个账单和运输获取哈希值
请帮忙!!!
class Address < ActiveRecord::Base
attr_accessible :name,:first_name,:last_name,:address1,:address2,:city,:state,:zip,:phone,:billing_default,: user_id,:billing_address, :shipping_address
belongs_to :user
has_many :billing_addresses, :class_name => "Order", :foreign_key => "billing_address_id"
has_many :shipping_addresses, :class_name => "Order", :foreign_key => "shipping_address_id"
class Order < ActiveRecord::Base
attr_accessible :cart_id, :order_no, :sales_tax, :shipping_fee,:total,:order_state,:gateway_type,:transaction_id,:transaction_status,:ip_address,:card_verification,:card_number,:billing_address_id,:shippin g_address_id,:first_name,:last_name,:user_id,:card_expires_on,:authenticity_token
belongs_to :cart
belongs_to :user
belongs_to :billing_address, :class_name => "Address"
belongs_to :shipping_address, :class_name => "Address"
attr_accessor :card_number
has_many :transactions, :through => :order_id
has_many :invoices
has_many :order_details
最佳答案
这是一个稍微复杂的问题,你会发现。
首先,问问自己:如果账单地址和送货地址相同,您真的只想插入一个地址吗?
- 一位客户想要更改送货地址。您将需要创建另一个地址记录并保留原始地址记录的逻辑。
- 一般来说,避免在订单完成后更新帐单地址和送货地址,因为这会损害数据的完整性。一旦订单关闭,就是这样;这些地址应该是固定的。当订单需要不同的送货地址时,请避免它与账单地址之间存在依赖关系。
现在,假设您要继续。
使用嵌套表单
隐藏帐单字段,并在映射到 order.bill_to_shipping_address
的表单中添加一个复选框。默认选中。如果未选中,则显示账单地址。
$('input[name="order[bill_to_shipping_address]"]').on 'click', ->
if $(this).is ':checked'
$('fieldset.billing_fields').hide()
else
$('fieldset.billing_fields').show()
在您的订单模型中:
accepts_nested_attributes_for :shipping_address
accepts_nested_attributes_for :billing_address, reject_if: :bill_to_shipping_address
这种方法的缺点是,如果存在验证错误,并且用户碰巧改变主意并将账单寄到不同的地址,账单表单将不会出现,因为它被拒绝了。
使用表单对象
这可能看起来更复杂,但它是一个更简洁的解决方案。
See 7 Patterns for refactoring ActiveRecord Objects .
构建一个表单对象。我从我最近为 Rails 4 应用程序编写的代码中采用了这段代码。只是扭转你的关系。在我的例子中,一张订单有一个账单地址和一个送货地址;它不属于他们。
class OrderForm
include ActiveModel::Model
def self.model_name
ActiveModel::Name.new(self, nil, "Order")
end
def persisted?
false
end
attr_accessor :params
delegate :email, :bill_to_shipping_address, to: :order
# Removed most fields for brevity
delegate :name, :street, :street_number, to: :shipping_address, prefix: :shipping
delegate :name, :street, :street_number, to: :billing_address, prefix: :billing
# Removed most fields for brevity
validates :email, length: { maximum: 60 }, email_format: true
validates :shipping_name, :shipping_street, presence: true
validates :billing_name, presence: true, unless: -> { bill_to_shipping_address }
def initialize(params = nil)
@params = params
end
def submit
populate
if valid?
order.save!
true
else
false
end
end
def order
@order ||= Order.new
end
private
def shipping_address
@shipping_address ||= order.build_shipping_address
end
def billing_address
@billing_address ||= order.build_billing_address
end
def populate
order.email = params[:email]
order.bill_to_shipping_address = params[:bill_to_shipping_address]
shipping_address.name = params[:shipping_name]
# etc...
unless order.bill_to_shipping_address?
billing_address.name = params[:billing_name]
# etc...
end
end
end
然后从 Controller :
def new
@order_form = OrderForm.new
end
def create
@order_form = OrderForm.new(params[:order])
if @order_form.submit
# order saved, do whatever
else
render 'new'
end
end
您的表单现在不关心嵌套的属性和属性。很干净。
= form_for @order do |f|
= f.text_field :email
= f.text_field :shipping_street
= f.text_field :billing_street
# etc...
关于ruby-on-rails - 电子商务运输和帐单地址到 rails 中的一张表中,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17840166/