Reputation: 3164
I have a quote
which has many shipping methods
. When I save the quote
, the shipping method prices are not updated when I use .first_or_initialize
. I have also tried setting autosave: true
on my association like so:
quote.rb
has_many :shipping_methods, dependent: :destroy, autosave: true
I have a callback which refreshes my shipping methods & their prices (quote.rb).
before_save :refresh_shipping_rates
def refresh_shipping_rates
ShippingMethod.refresh_rates(self, admin = true)
end
My ShippingMethod.refresh_rates function (shipping_method.rb):
def refresh_rates(record, admin)
#api call that returns a list of rates
updated_rates.each do |i|
rate = record.shipping_methods.where(name: i.name).first_or_initialize
rate.price = i.price
end
end
My quote is updated via a form submission to my update
action.
def update
@quote = Quote.find(params[:id])
@quote.update(parameters)
if @quote.valid?
flash[:notice] = []
flash[:notice] << "Successfully Updated"
render "update"
else
flash[:error] = []
@quote.errors.full_messages.each do |message|
flash[:error] << message
end
render "layouts/fail"
end
end
I assume the shipping_methods
should be updated simply because they are associated to the parent record that is being updated even though none of their attributes are submitted through the form.
Upvotes: 0
Views: 146
Reputation: 301
This method should be:
def refresh_rates(record, admin)
#api call that returns a list of rates
updated_rates.each do |i|
rate = record.shipping_methods.where(name: i.name).first_or_initialize
rate.price = i.price
end
end
to:
def refresh_rates(record, admin)
#api call that returns a list of rates
updated_rates.each do |i|
rate = record.shipping_methods.where(name: i.name).first_or_initialize
rate.price = i.price
rate.save
end
end
OR:
def refresh_rates(record, admin)
#api call that returns a list of rates
updated_rates.each do |i|
rate = record.shipping_methods.where(name: i.name).first_or_initialize(price: i.price)
end
end
Upvotes: 0
Reputation: 23327
When you call
rate = record.shipping_methods.where(name: i.name).first_or_initialize
shipping_method
is loaded from DB to a new object in memory that is not associated with quote
. You should either:
shipping_method
association (without calling any methods that fetches them from the DB), orshipping methods
separatelyI would advise to try 1).
Upvotes: 2