hi, i'm very new to ruby and rails so be gentle. i am trying to set up
a form that uses some validation but i'm having issues. i have a
controller class that contains 2 methods: one for showing the form and
another for processing the form. like so:
def show_form
store = Store.find_by_id(session[:store_id])
@all_balls = store.balls
@ball_sizes = store.ball_sizes
end
def complete_form
@picked_ball = session[:picked_ball]
if check_nil @picked_bread, 'Please choose a ball.'
return
end
@picked_ball_size = session[:picked_ball_size]
if check_nil @picked_ball_size, 'Please choose a ball size.'
return
end
# save stuff off into db
end
def check_nil(var_to_check, message)
if var_to_check.nil?
flash[:notice] = message
redirect_to :back
return true
end
false
end
my problem is that if the user selects a ball but forgets to select a
ball size, i go back to the form but it seems that i've lost all memory
of @picked_ball. i don't want to user to have to select the ball again.
i want it to be selected when the page is redisplayed with the error.
do i have to put this stuff in the session? i hope i don't because
there are actually a lot more items on the page, i've cut it down so my
post isn't quite as long.
also, here is my form:
<% form_tag(:action => 'complete_form') do %>
<h3>balls</h3>
<% for ball in @all_balls %>
<%= radio_button_tag 'picked_ball', ball.name, @picked_ball ==
ball.name %> <%= ball.name %><br />
<% end %>
<% for size in @all_sizes %>
<%= radio_button_tag 'picked_size', size.name, @picked_size ==
size.name %> <%= size.name %><br />
<% end %>
Typically one deals with this by re-rendering the form, not by
redirecting. You'll very often see this pattern:
@foo = Foo.new params[:foo]
if @foo.save#success
redirect_to ...
else
render :action => 'new'
end
thanks for the help, fred. i'm still a little confused. it is my
understanding that "actions" are methods in the controller. would that
code you posted be in a new def? i.e.
def new
# code you posted
end
are you saying i need to have the show and the handle performed by the
same method? that doesn't make sense to me as in the 'show' case, i'm
not looking for anything but in the 'complete' case, i am. how do i
know what i need to do if i have only one method doing both?
is there some tutorial somewhere you could point me to that goes in
depth on forms and best practices in using them? a tutorial that goes
into one controller method v. two; model object forms v. forms with just
fields on them, etc.
ok, i think i understand now after playing with it for a bit. it looks
like the 'render :action => new' runs the code from the new method but
with all the context of the method from which it came where as
redirect_to starts with a clean context.
so, i still have 2 actions (methods) show and complete but if i find an
error in complete, i now *render* show again and have all the context of
what i had in complete. when i used redirect_to, it also went to show
but it cleared out the context.
ok, i think i understand now after playing with it for a bit. it
looks
like the 'render :action => new' runs the code from the new method but
with all the context of the method from which it came where as
redirect_to starts with a clean context.
It does not run the new method at all. It just renders the template
that the new action would have rendered.
So in a typical example, the new method would just do
def new
@foo = Foo.new
end
ie the new method just starts out with an empty (all attributes set to
the defaults) instance of Foo.
If you call render from your create method then instead of having that
empty instance of Foo, you've got the one you created from the user
input so all the fields the user had filled it would be filled in and
so on.
so, i still have 2 actions (methods) show and complete but if i find
an
error in complete, i now *render* show again and have all the
context of
what i had in complete. when i used redirect_to, it also went to show
but it cleared out the context.