Problem creating a multi-step wizard based on Hobo Lifecycle

26 views
Skip to first unread message

afinetooth

unread,
Feb 17, 2009, 12:03:56 AM2/17/09
to Hobo Users
Hi,

Sorry to double-post, but I also piggybacked on this other recent
lifecycle question, here:
http://groups.google.com/group/hobousers/browse_thread/thread/7fc6dd46e51d3cc5

I could really use the help so I wanted to give this its own subject
and get a bit more visibility. Please forgive...

PROBLEM
I am trying to use a Hobo Lifecycle to define a multi-step wizard,
which steps a user through the creation of a Delivery.

The user is asked a series of questions, whose input builds up the
single model, Delivery.

The wizard does not cross models, or use more than one model.

I have defined the lifecycle as follows:

--------------
lifecycle do

state :begun, :given_date, :given_time_of_day, :given_fromzip, :given_tozip, :given_service_level, :given_building_info, :requested

create :begin,
:params => [ :customer ],
:become => :begun,
:available_to => "User",
:user_becomes => :customer

transition :give_items,
{ :begun => :given_items },
:params => [ :delivery_items ],
:available_to => :all do
end

transition :give_date,
{ :given_items => :given_date },
:params => [ :date ],
:available_to => :all do
end

transition :give_time_of_day,
{ :given_date => :given_time_of_day },
:params => [ :time_of_day ],
:available_to => :all do
end

transition :give_fromzip,
{ :given_time_of_day => :given_fromzip },
:params => [ :from_zip ],
:available_to => :all do
end

transition :give_tozip,
{ :given_fromzip => :given_tozip },
:params => [ :to_zip ],
:available_to => :all do
end

transition :give_service_level,
{ :given_tozip => :given_service_level },
:params => [ :service_level ],
:available_to => :all do
end

transition :give_building_info,
{ :given_service_level => :given_building_info },
:params => [ :building_flights, :building_elevator ],
:available_to => :all do
end

end
-------

I am experiencing two issues with this approach:

1) When I use any value for :available_to besides :all, for
instance :customer, I get an error of Undefined Method
"customer_is?" (I have set the permissions properly, I believe)

2) While I am able to obtain a form page for each of the lifecycle
steps, such as :give_date---where, upon entering
http://localhost:3000/deliveries/6/give_date, I get a page titled
"Give date" with a submit button labeled "Give date"---the form page
itself is blank.

I was expecting to receive a form page for each step comprised of the
fields defined in :params for each transition.

So, using the above step, :give_date, as such:

transition :give_date,
{ :given_items => :given_date },
:params => [ :date ],
:available_to => :all do
end

I would expect to see a form page entitled "Give date," with one form
field, Date, and a submit button labeled "Give date."

But the Date field is missing.

BTW, submission of the (empty) form page _does_ transition the model
properly to its new state.

Can anyone help me with these two issues?

Is the lifecycle code fully cooked in the controller and view layers,
btw? Or do I need to add some code to my controllers?

TIA,
James

afinetooth

unread,
Feb 17, 2009, 6:12:08 AM2/17/09
to Hobo Users
Answering my own question here, in case it helps someone else out
there working on Lifecycles. (Brilliant, btw.)

(2) The reason the relevant form fields were not showing is due to a
syntax error, not corrected in current documentation.

I found the correct syntax in this wiki, created by another user
(thank you!):

http://wiki.github.com/tablatom/hobo/lifecycles

So, in your transition steps, instead of declaring your fields in an
array called :params, the array is called :update.

So, instead of:

transition :give_date,
{ :given_items => :given_date },
:params => [ :date ],
:available_to => :all do
end

It should be:

transition :give_date,
{ :given_items => :given_date },
:update => [ :date ],
:available_to => :all do
end

That solved my problem (2).

Still working on (1).

-james

On Feb 16, 9:03 pm, afinetooth <afineto...@gmail.com> wrote:
> Hi,
>
> Sorry to double-post, but I also piggybacked on this other recentlifecyclequestion, here:http://groups.google.com/group/hobousers/browse_thread/thread/7fc6dd4...
>
> I could really use the help so I wanted to give this its own subject
> and get a bit more visibility. Please forgive...
>
> PROBLEM
> I am trying to use a HoboLifecycleto define a multi-step wizard,
> steps, such as :give_date---where, upon enteringhttp://localhost:3000/deliveries/6/give_date, I get a page titled
> "Give date" with a submit button labeled "Give date"---the form page
> itself is blank.
>
> I was expecting to receive a form page for each step comprised of the
> fields defined in :params for eachtransition.
>
> So, using the above step, :give_date, as such:
>
>    transition :give_date,
>                 { :given_items => :given_date },
>                 :params => [ :date ],
>                 :available_to => :all do
>     end
>
> I would expect to see a form page entitled "Give date," with one form
> field, Date, and a submit button labeled "Give date."
>
> But the Date field is missing.
>
> BTW, submission of the (empty) form page _does_transitionthe model
> properly to its new state.
>
> Can anyone help me with these two issues?
>
> Is thelifecyclecode fully cooked in the controller and view layers,

Brett Nelson

unread,
Feb 17, 2009, 11:09:14 AM2/17/09
to Hobo Users
> I found the correct syntax in this wiki, created by another user
> (thank you!):

It was Jakob Suder who wrote that documentation after I had
initially submitted a hacked up solution to Email Activation. Have
made minor edits to it since then though, glad you got it to work!

Brett

afinetooth

unread,
Feb 18, 2009, 12:09:27 AM2/18/09
to Hobo Users
Great. Well, thanks to you and to Jakob.

IMHO, Hobo is one of the most interesting and useful projects since
Rails itself. I wish I had more time to help snap some of the pieces
into place like the documentation efforts, etc.

It's been exceedingly helpful and has added lots of efficiency to my
work.

In the meantime, I have another question which I hope someone can
answer.

When using a Lifecycle to build something like this wizard, where is
the best place to put an HTTP directive after a given step?

In other words, I would like to declare where to send a user after
they have visited my :give_date step--in particular to go to
the :give_time_of_day step, at http://localhost:3000/deliveries/give_time_of_day.

Where is the best place to do this?

I would love to be able to put it in the do...end block at the end of
my transition declaration. But it seems like it might be more
appropriate in the controller.

Can anyone show me how such a directive would look in the do..end
block of the transition step? (I'm also a relative newbie to Rails, so
forgive me if this is obvious, but I don't know how to call a
controller action, essentially a redirect_to, from within a model. I
also don't know if it's inappropriate.)

SO, LOOKING FOR....

transition :give_date,
{ :given_items => :given_date },
:update => [ :date ],
:available_to => :all do
<WHAT GOES HERE>
end

thanks again,
j

Tom Locke

unread,
Feb 18, 2009, 7:02:55 AM2/18/09
to hobo...@googlegroups.com
> In other words, I would like to declare where to send a user after
> they have visited my :give_date step.....

>
> I would love to be able to put it in the do...end block at the end of
> my transition declaration. But it seems like it might be more
> appropriate in the controller.

Yes, it should go in the controller. There are docs for that in the
lifecycles chapter and the controllers and routing chapter.

Tom

afinetooth

unread,
Feb 18, 2009, 8:57:48 AM2/18/09
to Hobo Users
Thanks, Tom.

Yes, I re-read the Lifecycles section of the Manual and finally got
how to do it:

You want to override the second controller action generated by your
Lifecycle step (creator or transition), which is the do_<step_name>
action.

Then in that step, you want to supply the :redirect argument to the
do_transition_action method (or do_creator_action, for a creator),
passing it the symbol name for the next step in your lifecycle.

So, for example:

For the transition step called "give_date", which should then go to
the transition step called "give_time_of_day", the controller should
look like this:

------------------------------------------------------------------
class DeliveriesController < ApplicationController
[...]

def do_give_date
do_transition_action :give_date, :redirect => :give_time_of_day
end

[...]
end
------------------------------------------------------------------
Reply all
Reply to author
Forward
0 new messages