I'm fairly new to both Ruby and Rails (using 2.3.8), so forgive me if I'm missing something really obvious here but I've been struggling with this for a while and my searches have been fruitless.
In my code I have Plans, and a Plan has many Plan_Steps. Each Plan_Step has a number (to indicate '1st', '2nd', etc). I have a form to update a Plan, and I need to validate that each Plan_Step has a unique number. The code below might give a better explanation of the design:
models/plan.rb:
Class Plan < ActiveRecord::Base
has_many :plan_steps
accepts_nested_attributes_for :plan_steps, :allow_destroy => true
validate :validate_unique_step_numbers
# Require all steps to be a unique number
def validate_unique_step_numbers
step_numbers = []
plan_steps.each do |step|
#puts step.description
if !step.marked_for_destruction? && step_numbers.include?(step.number)
errors.add("Error Here")
elsif !step.marked_for_destruction?
step_numbers << step.number
end
end
end
controllers/plans_controller.rb:
...
def update
@plan = Plan.find(params[:id])
if @plan.update_attributes(params[:plan])
#Success
else
#Fail
end
end
Now when my form submits an update, the params hash looks like this:
{"commit"=>"Submit",
"action"=>"update",
"_method"=>"put",
"authenticity_token"=>"NHUfDqRDFSFSFSFspaCuvi/WAAOFpg5AAANMre4x/uu8=",
"id"=>"1",
"plan"=>{
"name"=>"Plan Name",
"plan_steps_attributes"=>{
"0"=>{"number"=>"1", "id"=>"1", "_destroy"=>"0", "description"=>"one"},
"1"=>{"number"=>"2", "id"=>"3", "_destroy"=>"0", "description"=>"three"},
"2"=>{"id"=>"2", "_destroy"=>"1"}},
"controller"=>"plans"}
The database contains entries for Plan_Steps with the following:
ID=1, Number=1, Description='one'
ID=2, Number=2, Description='two'
Notice that ID=2 exists with Number=2, and what I'm trying to do is delete ID=2 and create a new entry (ID=3) with Number=2.
OK, so with that set up, here is my problem:
When I call plan_steps in the validation, it appears to be pulling the values from the database instead of from the params[] array passed to update_attributes.
For example, if I uncomment the 'puts' line in the validation, I see the descriptions of the Plan_Steps as they exist in the database, not as they exist from the passed-in parameters. This means I can't validate the incoming Plan_Steps.
I can't do validation in the Plan_Steps model, either, since unless I'm mistaken the validation will occur against the database (and not the parameters passed in).
I apologize if this is a poorly worded question, but it's fairly specific. If you need any clarification, please ask.
And remember, I'm a noob, so I could easily be making some really stupid mistake.