Reputation: 401
I have followed railscast #198 Edit Multiple Individually and it works 100% for editing multiple records from a single form.
However, I would like to also create new records from the same form if the record. i.e. in the controller assess the hash of params from the form, update those records that exist and create the records that don't exist.
Also, if any validation errors occur they should be caught and passed back.
This in the controller works and will update correctly if the fields for the new record aren't present @costs = IngredientCost.update(params[:ingredient_costs].keys, params[:ingredient_costs].values).reject { |item| item.errors.empty? }
For the fields for the new records I am currently creating an artibrary large unique number as the record id (I'm not sure if this is right to do) and then the message comes back that it cannot be saved because the id doesn't exist, which is to be expected as I it doesn't exist.
I've tried the following two snippets as a stab in the dark but not really sure which way I should be going..
@costs = IngredientCost.find_or_initialize_by_id(:id => params[:ingredient_costs].keys).update(params[:ingredient_costs].keys, params[:ingredient_costs].values).reject { |i| i.errors.empty? }
and
params[:ingredient_costs].each do |ingredient_cost|
@cost = IngredientCost.find_or_initialize_by_ingredient_id_and_user_id(:ingredient_id => ingredient_cost[1]["ingredient_id"], :user_id => current_user.id)
@cost = IngredientCost.update(:ingredient_id => params[:ingredient_costs][ingredient_cost[0]]["ingredient_id"], :quantity => params[:ingredient_costs][ingredient_cost[0]]["quantity"], :price_per_unit => params[:ingredient_costs][ingredient_cost[0]]["price_per_unit"], :weight_id => params[:ingredient_costs][ingredient_cost[0]]["weight_id"])
Neither seem to work.
I've seen this work before but for updating/creating nested attributes from one form. I don't really want to have to go that route with this.
Upvotes: 2
Views: 5818
Reputation: 401
I eventually resorted to saving the multiple records through a parent model which already had the correct associations.
I followed Railscast #196 Nested Model Forms which was fairly similar to above only saving to another model and placing accepts_nested_attributes_for
in that model's *.rb.
Remember to move the routes.
Move the controller code to the receiving action of the parent model.
My form in the viewer now looks like this (in haml format):
= form_for @user, :remote => true do |f|
= f.fields_for :ingredient_costs do |builder|
// fields inserted here
It took me a couple hours to realise I had to use builder.object...
to get to the child that I actually am interested. The .object
class wasn't obvious to me.
Anyway, hope this was useful to someone. I think SybariteManoj's answer looks like a good deal, but I couldn't get it to work.
Upvotes: 3
Reputation: 3093
You can try following snippet:
@costs = []
params[:ingredient_costs].each do |ingredient_cost|
if ingredient_cost[:id].blank?
cost = IngredientCost.create(ingredient_cost)
@costs << cost
else
cost = IngredientCost.find(ingredient_cost[:id])
cost.update_attributes(ingredient_cost)
@costs << cost
end
end
P.S. I haven't tested it yet. But for the re-rendering the edit page with the errors, the @costs variable has the data with errors if any.
Upvotes: 1