Oliver
Oliver

Reputation: 851

rails nested attributes validations with has_one relation condition

I have an Order model which has_one required delivery_address and an optional billing_address. Order has an bool attribute has_billing_address. In my form i'm accepting nested attributes:

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

There are validations on both address models for field presence. I only want to create the billing_address if @order.has_billing_address? is true and the validations on billing_address should also just trigger when there is a billing address.

My order controller looks like this:

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

I'm really stuck on this - there should be no validation on billing_address if @order.has_billing_address? is false - i can't use an if proc on the validation of the BillingAddress model cause there are times where there is no order associated to the model. And there is another problem when returning to action address if order already exists and no billing address is set i have to show the nested billing address form again so i call @order.billing_address = BillingAddress.new then it tells me that it cant be saved cause the validations fail for it.

Any ideas? It's a little bit confusing with nested attributes. Thanks in advance!

Upvotes: 0

Views: 709

Answers (1)

Rails Guy
Rails Guy

Reputation: 3866

Try with this validation in your billing address model:

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

Edit (Try with Proc) :

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

Thanks

Upvotes: 1

Related Questions