best way to validate input values..

Hi, I have a form that submits values from text fields and a check box.
The values posted are: camp location name, number of nights, number of
parents, number of children, value from the check box "family claim".
Where camp name can't be nil, nights can't be more than 2, parents and
children together can't be more than 8 and if there are no children
specified check box can't be checked. Here's my unsuccessful
implementation for this:

def add_to_cart
begin
   cart=find_cart
   camp_loc = params[:camp][:id]
   nights=params[:nights]
   parents=params[:parents]
   children=params[:children]
   family_rate_claim=params[:family_claim]
rescue
   redirect_to_booking("Invalid input.")
end
if camp_loc.blank? || nights.blank? || parents.blank?
    redirect_to_booking("Fields with '*' are required fields.")
elsif (nights.to_i > 2) || ((parents.to_i + children.to_i) > 8)
    redirect_to_booking("Limitation: Maximum stay of 2 nights with group
of maximum 8 people.")
elsif children.nil? and family_rate_claim == "1"
    redirect_to_booking("You are not eligible for claiming family
rate.")
else
    ....add the stuff in the cart
end
end

def redirect_to_booking(msg)
flash[:notice]=msg
render :action => :online_booking
end

When I click the button without giving anything as the input I get this:

Render and/or redirect were called multiple times in this action. Please
note that you may only call render OR redirect, and at most once per
action. Also note that neither redirect nor render terminate execution
of the action, so if you want to exit an action after redirecting, you
need to do something like "redirect_to(...) and return".

but what I want is to to get redirected to the same page with error
information.
thanks..

the "render or redirect called multiple times" error is because you haven't called 'return' after you called 'render' or indeed 'redirect_to'. It doesn't actually do the render or redirect immediately. It only occurs after the method has returned.

RobL

Jay Pangmi wrote:

I wouldn't do any vaildation in the controller, its messy and not ideal.

I'd have some kind of 'Booking' object which presumably is what you are adding to your cart and validate it inside that using the rails validation helpers.

RobL

Jay Pangmi wrote:

Jay Pangmi wrote:

you specific problem here is -

...

rescue
   redirect_to_booking("Invalid input.")
end

You render here

if camp_loc.blank? || nights.blank? || parents.blank?
    redirect_to_booking("Fields with '*' are required fields.")
elsif (nights.to_i > 2) || ((parents.to_i + children.to_i) > 8)
    redirect_to_booking("Limitation: Maximum stay of 2 nights with group
of maximum 8 people.")
elsif children.nil? and family_rate_claim == "1"
    redirect_to_booking("You are not eligible for claiming family

And also here

Do .

return( redirect_to_booking("Invalid input.") )

So your code doesn't fall through.

Jay Pangmi wrote:

you specific problem here is -

...

> rescue
> redirect_to_booking("Invalid input.")
> end

You render here

> if camp_loc.blank? || nights.blank? || parents.blank?
> redirect_to_booking("Fields with '*' are required fields.")
> elsif (nights.to_i > 2) || ((parents.to_i + children.to_i) > 8)
> redirect_to_booking("Limitation: Maximum stay of 2 nights with group
> of maximum 8 people.")
> elsif children.nil? and family_rate_claim == "1"
> redirect_to_booking("You are not eligible for claiming family

And also here

Do .

return( redirect_to_booking("Invalid input.") )

So your code doesn't fall through.

I think there's a relationship between the problem you are
experiencing and the face that you are performing validations in your
controller and not your model. As Rob said above, you should move the
validations:

if camp_loc.blank? || nights.blank? || parents.blank?
elsif (nights.to_i > 2) || ((parents.to_i + children.to_i) > 8)
elsif children.nil? and family_rate_claim == "1"

to your model and use ActiveRecord validations:

http://api.rubyonrails.org/classes/ActiveRecord/Validations/ClassMethods.html

and

callbacks:

http://api.rubyonrails.com/classes/ActiveRecord/Callbacks.html

to implement the validations in your models

Then you could call save (or valid?) and use error_messages_for (vs.
flash) to display your messages. This is all in addition to calling
return with each render.

Jay Pangmi wrote:

you specific problem here is -

...

> rescue
> redirect_to_booking("Invalid input.")
> end

You render here

> if camp_loc.blank? || nights.blank? || parents.blank?
> redirect_to_booking("Fields with '*' are required fields.")
> elsif (nights.to_i > 2) || ((parents.to_i + children.to_i) > 8)
> redirect_to_booking("Limitation: Maximum stay of 2 nights with group
> of maximum 8 people.")
> elsif children.nil? and family_rate_claim == "1"
> redirect_to_booking("You are not eligible for claiming family

And also here

Do .

return( redirect_to_booking("Invalid input.") )

So your code doesn't fall through.

I think there's a relationship between the problem you are
experiencing and the face that you are performing validations in your
controller and not your model. As Rob said above, you should move the
validations:

if camp_loc.blank? || nights.blank? || parents.blank?
elsif (nights.to_i > 2) || ((parents.to_i + children.to_i) > 8)
elsif children.nil? and family_rate_claim == "1"

to your model and use ActiveRecord validations:

http://api.rubyonrails.org/classes/ActiveRecord/Validations/ClassMethods.html

and

callbacks:

http://api.rubyonrails.com/classes/ActiveRecord/Callbacks.html

to implement the validations in your models

Then you could call save (or valid?) and use error_messages_for (vs.
flash) to display your messages. This is all in addition to calling
return with each render.