I'm struggling to see the natural solution to this with a nod to
resources and keeping things restful.
The problem is based around a Customer model with a fairly standard
resource based controller (new, create, edit...)
The registration is really a two step process:
1. First enter a postcode/zip and then search national database of
addresses to offer selection of possible addresses for this postcode/
zip in a select box.
2. User then selects an address and proceeds to what is essentially
the /customers/new action with the address fields already populated,
just requiring customer name and contact details to be filled in.
I don't really want the new Customer object created until the final
stage of name and contact details entry.
I was thinking maybe a NewCustomerAddress resource with the 'index'
action presenting the postcode/zip search box which submits to the
'new' action which looks up the submited postcode and renders
available addresses in a select box.
The user then selects the suitable address and submits the form, which
requests the Customer 'new' action. Before rendering customer/new it
adds the address detail to the new Customer object to be displayed in
the form (user may then also tweak address if neccessary).
Am I using resources correctly regarding the NewCustomerAddress? Could
it be bundled in to the Customer resource?
That's pretty close to what I have done in similar situations.
Speaking from a rails point of view, I have found that whenever I need
to add more than the 7 basic actions or need to create an object with
a multi-step process, that it is time to break the functionality out
into more than one controller (i.e. resource). This has really helped
to keep my code clean.
The only difference I would have to what you did is instead of making
the capturing of the zip code the "index" action of the
NewCustomerAddress controller, I would make it a "new" and a "action".
The "new" action would show the form to capture the zipcode and the
"create" action would redirect and pass the value to the customer
controller's "new" action.
Also, I would probably rename the NewCustomerAddress resource to
something like CustomerAddressZip or ZipCodeSearch.
Other than that I think you are on the right track. The main point is
to not try to shoe-horn in all your actions into one controller. Keep
each controller to the basic seven. When you find yourself needing
more actions, it is time to create a new controller.
Oops! That should read: "I would make it a 'new' and 'create' actions.
Thanks Jamey, glad I'm not far off.
With regard to action names, I can see what you mean but I think
you've missed a step out of my process. I was thinking:
index: renders textbox to enter zip code and submits to 'new'
new: looks up zipcode and renders select box of addresses at zipcode,
user makes selection and form submits to 'create'
create: redirect to the customer controller's 'new' action, passing
unqiue reference to selected address
I think we're more or less saying the same thing though.
Correct me if I'm wrong, but what you are really looking for is just
an address lookup step in the middle of the model creation process.
Why don't you start with the Customer#new that shows the zip code
field only at first. The user enters the code and you send an Ajax
call to the CustomersController#address_lookup or
AddressesController#show (finding by given zip as opposed to usual ID)
and if you get the response, you populate the address selector and
show the rest of the form, including the "Submit" button.
My point is that you don't have a huge wizard-like multi-step process.
All you need is a simple lookup, so why don't just do that?