【问题标题】:rails nested attributes validations with has_one relation condition使用 has_one 关系条件进行嵌套属性验证
【发布时间】:2013-08-29 12:17:59
【问题描述】:

我有一个 Order 模型,其中包含一个必需的 delivery_address 和一个可选的 billing_address。订单有一个布尔属性 has_billing_address。在我的表单中,我接受嵌套属性:

class Order < ActiveRecord::Base

  has_one :delivery_address, dependent: :destroy
  has_one :billing_address, dependent: :destroy

  accepts_nested_attributes_for :delivery_address, allow_destroy: true
  accepts_nested_attributes_for :billing_address, allow_destroy: true

end

两种地址模型都对字段存在进行了验证。如果@order.has_billing_address 我只想创建billing_address?为真,并且 billing_address 上的验证也应该只在有帐单地址时触发。

我的订单控制器如下所示:

def address
  if session['order_id'].blank?
    @order = Order.new
    @order.delivery_address = DeliveryAddress.new
    @order.billing_address = BillingAddress.new
  else
    @order = Order.find(session['order_id'])
    ##### PROBLEM fails cause of validation:
    @order.billing_address = BillingAddress.new if @order.billing_address.blank?
  end
end

def process_address
  has_billing_address = params[:order][:has_billing_address].to_i
  params[:order].delete(:billing_address_attributes) if has_billing_address.zero?
  if session['order_id'].blank?
    @order = Order.new(params[:order])
    @order.billing_address = nil if has_billing_address.zero?
    @order.cart = session_cart
    if @order.save
      session['order_id'] = @order.id
      redirect_to payment_order_path
    else
      render "address"
    end
  else
    @order = Order.find(session['order_id'])
    @order.billing_address = nil if has_billing_address.zero?
    if @order.update_attributes(params[:order])
      redirect_to payment_order_path
    else
      render "address"
    end
  end
end

我真的坚持这一点 - 如果 @order.has_billing_address 不应该对 billing_address 进行验证?是错误的 - 我不能在 BillingAddress 模型的验证中使用 if proc,因为有时没有与模型关联的订单。如果订单已经存在并且未设置帐单地址,则返回操作地址时还有另一个问题我必须再次显示嵌套的帐单地址表格所以我调用@order.billing_address = BillingAddress.new 然后它告诉我它无法保存导致验证失败。

有什么想法吗?嵌套属性有点令人困惑。提前致谢!

【问题讨论】:

    标签: ruby-on-rails ruby-on-rails-3 validation


    【解决方案1】:

    尝试在您的帐单地址模型中进行此验证:

    validate :field_name, :presence => true, :if => 'order.has_billing_address?'
    

    编辑(尝试使用 Proc):

    validate :field_name, :presence => true, if: Proc.new { |c| c.order.has_billing_address?}
    

    谢谢

    【讨论】:

    • 感谢您的快速回复。如果验证是这样的,则根本不会触发验证。
    • 好的,验证被触发,但是当不存在订单时,可能是这种情况我:获取未定义的方法`has_billing_address?对于 nil:NilClass
    • 如果你有嵌套的属性,顺序应该总是在那里。否则,您可以传递多个条件,例如: validate :field_name, :presence => true, if: Proc.new { |c| c.order.present? && c.order.has_billing_address?}
    • 好的,我改变了订单的工作方式。所以现在总是存在秩序。如果我使用 proc 条件,则在保存 has_billing_address 之前不会触发验证,这意味着如果我两次更新记录就会触发它。有什么解决方法吗? proc.new 读取 db 中 order 的当前值..
    • aah 我只是在调用 update_attributes 之前使用 has_billing_address 更新订单,然后对 billing_address 进行验证。谢谢!
    猜你喜欢
    • 1970-01-01
    • 2012-05-09
    • 2014-01-08
    • 2017-07-13
    • 1970-01-01
    • 1970-01-01
    • 2014-05-16
    • 1970-01-01
    • 2013-05-12
    相关资源
    最近更新 更多