So I have a user form form_for that accepts nested attributes from account_prices. Whats happening is on my user controller I have this private method.
def pre_build_user_account_prices
if @user.account_prices.empty?
@accountable_default = @user.account_prices.build(status: 'default')
@accountable_temporary = @user.account_prices.build(status: 'temporary')
else
@accountable_default = @user.account_prices.where(status: 'default')
@accountable_temporary = @user.account_prices.where(status: 'temporary')
end
end
reason for the condition is, if I don't do a check here it will render 2 forms. an empty form and with data form. So checking is a need here
but my problem is this.Im on edit route, and when I try to submit an invalid form it renders multiple empty forms. heres an image.
if I kept submitting invalid form it will render multiple times. I was thinking if checking through JS if theres a multiple child I will remove it. is that the best approach?
here's my asscociations
Class User
has_many :account_prices, as: :accountable, autosave: true
accepts_nested_attributes_for :account_prices
end
polymorphic
class AccountPrice
enum status: {default: 'default', temporary: 'temporary'}
validates :accountable, presence: true
validates :status, presence: true
validates :exp_start_date, presence: true, if: :is_temporary_status?
validates :exp_end_date, presence: true, if: :is_temporary_status?
belongs_to :accountable, polymorphic: true
belongs_to :variant_price_set, class_name: "Spree::VariantPriceSet"
belongs_to :shipping_method_price_set, class_name: "Spree::ShippingMethodPriceSet"
def is_temporary_status?
status == 'temporary'
end
end
user controller
Class UsersController
before_action :pre_build_user_account_prices, only: :edit
def update
if @user.update_attributes(user_params)
flash.now[:success] = Spree.t(:account_updated)
redirect_to show_admin_user_path(@user)
else
render :edit
end
end
def pre_build_user_account_prices
if @user.account_prices.empty?
@accountable_default = @user.account_prices.build(status: 'default')
@accountable_temporary = @user.account_prices.build(status: 'temporary')
else
@accountable_default = @user.account_prices.where(status: 'default')
@accountable_temporary = @user.account_prices.where(status: 'temporary')
end
end
end

I guess when you're trying
@user.account_prices.where(...it is reading data which is not persisted to the db too. I mean the account_prices which was just build in the previous step.Try,
reload, reloads the object's attributes from the database
Also, when using accept_nested_attributes for to update an existing entry, you need to make sure that id of the nested object for which you're accepting nested attribute for is part of the attributes passed.