Thanks for the screencast. it's an Interesting subject.
Usually I love your Railscasts but I feel this one was a bit rushed. The screens changed too quickly.
I was disappointed when you skipped the validations as it's the harder part.
The partial layout at end seems interesting and deserve a full episode on when to use it.
Struggling on getting the validations setup properly.. Im using devise, so the user sign up page begins with: email, password, password confirmation witch are all handled and validated by devise.. Now im getting a
"NoMethodError in RegistrationsController#create".. undefined method `include?' for nil:NilClass"
after following the steps in that wicked tutorial exactly.. any ideas? Thanks
I've wrote rails engine https://github.com/vlado/rails_temporary_data that could be low level alternative when you have complex validations.
It just gives you helpers to easily save and manipulate temporary data (saved in separate table as serialized attribute) till you finish all steps (you'll need to define steps yourself).
I think it could even be useful in combination with wicked.
Now there's a problem with Simple Navigation - when I follow to next step (when user_steps_controller.rb runs) simple_navigation somehow forgots all the "global" variables like root_path etc., so that I get error in application layout
ruby
undefined local variable or method `root_path' for "user_steps":String
I'd like to add, that simply adding root_path in application layout works, so there's something wrong with =render_navigation.
If anyone uses those 2 gems and somehow solved this problem, please share. :)
I would recommend just directing a user to an after register flow rather than over-riding the create method totally, i've tried both, and it will cause you less pain.
I get this itchy feeling any time the model has to know what the controller is doing. Validation of the sort needed to get the field validation working always seem kind of hacky to me. I know there's been a few debates, but I tend to favor the side that saying validation should be moved to the controller because it already hooked into things like context and state (i.e. authorization).
(This does not mean this wasn't another great Railscast.)
Authorization and mass assignment protection can reasonably be moved to a controller and actually makes more sense there in many cases. Model validations should reside in the model or you risk having inconsistent data. Having different validations based on state of your model isn't all that hacky or uncommon, though it does require rigor to set that state variable re: https://github.com/schneems/wicked/wiki/Partial-Validation-of-Active-Record-Objects
I am also interested in this question.. in the first few steps of my multistep form I am working with user attributes, but in the next one I am working with user "interests" which is currently setup with a different model (related to the user using a HABTM)
You can definitely use for resources other than User. For instance, originally had User resource that included a bunch of additional information regarding the user's profile (address, age, phone #'s, etc.).
I decided that these attributes should be part of a different resource called RenterProfile (it's an app for renters), leaving nothing but the email address and password in the User resource. So I setup the appropriate controller, model, views and DB migration for this renter_profile resource. Once I had everything working (all the renter_profile fields within a single page/form, I then moved on to implementing a wizard for the renter_profile resource.
I followed Ryan's example pretty much verbatim simply swapping in renter_profile in place of user. I let my renter_profiles_controller perform the initial #create action with just a few basic fields (similar to creating the User with only the email and password). Then I created a renter_profile_steps controller (of course including the wicked gem same as Ryan's example). I placed the remaining attributes I wanted for the renter_profile into multiple form view files within the ~/views/renter_profile_steps directory.
The only hiccup I encountered was that get "renter_profile/steps" somehow ended up in my routes.rb file which messed everything up. Not sure how it ended up there (maybe wicked created it, but unlikely) or my coding partner did it without remembering... Regardless, with it removed, the renter_profile_steps_path began working correctly.
I think it's a little confusing that you're showing two forms; a user registration form and than two extra steps in a separate form, while really all three steps could go in one form, making it a lot more sustainable.
More important I was wondering how Wicked handles file uploads?
wondering if anyone has tried this by submitting the form by AJAX?
I've got the first step that creates a new Project, then we redirect to the project_steps_path to go to the actual first step of the wizard. This works fine until we submit the form via AJAX where we just keep getting a 302 response Moved Temporarily, the Project does get created and I think the redirect to project_steps works, but instantly redirects again to the Project/index view.
I'm hoping to be able to submit by AJAX and in the response get the next views HTML
Has anyone else experienced this or something similar?
Does this work in concert with a Twitter Bootstrap modal? I'd like to have my steps displayed inside a popup modal rather than render a new page. Can it be hacked to respond to JS requests?
Had a sneaky error on the last step with the re-direct. All the parameters updated my record properly, but got the following error: wrong number of arguments (1 for 0), _steps_controller.rb:57:in `redirect_to_finish_wizard'.
This is awesome, but what if I want the link_to to save the form data before it is clicked?
It seems wicked defaults to the form id to edit_put (maybe its a rails default?)
I cannot seem to over write this, but no matters since page per page i just want my link to save the data there, I thought I could call a submit action:
And then the java script on the page is:
$(document).ready(function() {
$('#my-link-check').click(function(event){
var form = document.getElementById("edit_put");
if(form!=null)
form.submit();
});
});
But this seems to not submit (does if have a breakpoint in firebug, odd) and then if that submit does work it doesnt goto the next page...
our "Save Document" buttons on these pages do work, and are just
submits. So not sure what critical piece I am missing to make this work.
Hi, very nice tutorial, I need to develop a very long form that will have many questions that will be optional based on the user inputs from a previous question for example:
Do you fever? Yes/No
(Questions appear in case user selected Yes)
Date it Started?
Temperature:
(Next question appears if user selected No)
Do you have allergies?
I will divide the form on several views but I would like some of the questions on the form only appearing if the users select the appropriate answer form the previous question.
Any ideas on how to implement this, thanks.
If I am using paperclip and have an upload option in first step.
Will the attachment be persistent in session/rack or I need to use some temporary table/model to store that file before the complete form is submitted ?
I developed a wizard using Angular JS. It is extremely simple and requires less code. It allows users to go back and change previous values. It's on github: https://github.com/bparanj/angular-wizard
Thanks for the screencast. I'm just wondering...is there a simple way to implement this while using devise? Right now, I'm thinking that I'd have to kind of hack the out my own create method in the UserRegistrationController that devise comes with.
Is there a reason the personal view uses form_for @user while the social view uses form_for current_user? Since the controller sets @user to current_user, I suspect the views got created at different times and there's no real difference in this case. Though it seems like @user would be the better choice, since the controller can … control that value.
+1, thanks Ryan Bates. This is awesome
Was just in the process of building wizard forms at work, you never seize to impress Ryan
*cease :)
Thank you Rees, Im a better man now that i can spell .. :)
Thanks for the screencast. it's an Interesting subject.
Usually I love your Railscasts but I feel this one was a bit rushed. The screens changed too quickly.
I was disappointed when you skipped the validations as it's the harder part.
The partial layout at end seems interesting and deserve a full episode on when to use it.
He just want to save the bandwidth ;-)
Let me know if you have problems with validations
Struggling on getting the validations setup properly.. Im using devise, so the user sign up page begins with: email, password, password confirmation witch are all handled and validated by devise.. Now im getting a
"NoMethodError in RegistrationsController#create".. undefined method `include?' for nil:NilClass"
after following the steps in that wicked tutorial exactly.. any ideas? Thanks
I've wrote rails engine https://github.com/vlado/rails_temporary_data that could be low level alternative when you have complex validations.
It just gives you helpers to easily save and manipulate temporary data (saved in separate table as serialized attribute) till you finish all steps (you'll need to define steps yourself).
I think it could even be useful in combination with wicked.
Any idea how to overwrite create method in Devise (code in users_controller.rb)?
And generally how to implement it correctly in Devise?
Did you see here? https://github.com/plataformatec/devise/wiki/_pages
Yeh, thank you.
Now there's a problem with Simple Navigation - when I follow to next step (when user_steps_controller.rb runs) simple_navigation somehow forgots all the "global" variables like root_path etc., so that I get error in application layout
I'd like to add, that simply adding root_path in application layout works, so there's something wrong with =render_navigation.
If anyone uses those 2 gems and somehow solved this problem, please share. :)
Follow @fabiano's link, create the registrations controller then replace '/an/example/path' with '/user_steps' . Hope this helps
helped a lot...
I would recommend just directing a user to an after register flow rather than over-riding the create method totally, i've tried both, and it will cause you less pain.
I get this itchy feeling any time the model has to know what the controller is doing. Validation of the sort needed to get the field validation working always seem kind of hacky to me. I know there's been a few debates, but I tend to favor the side that saying validation should be moved to the controller because it already hooked into things like context and state (i.e. authorization).
(This does not mean this wasn't another great Railscast.)
Authorization and mass assignment protection can reasonably be moved to a controller and actually makes more sense there in many cases. Model validations should reside in the model or you risk having inconsistent data. Having different validations based on state of your model isn't all that hacky or uncommon, though it does require rigor to set that state variable re: https://github.com/schneems/wicked/wiki/Partial-Validation-of-Active-Record-Objects
Nice!
Hi!
Thanks thanks Ryan Bates for this Interesting cast.
Can I use a wicked wizard to another model than the User.
Thanks for any help
Bardach
I am also interested in this question.. in the first few steps of my multistep form I am working with user attributes, but in the next one I am working with user "interests" which is currently setup with a different model (related to the user using a HABTM)
Thanks! Awesome work!
@nelsonkeating - see my response above.
You can definitely use for resources other than User. For instance, originally had User resource that included a bunch of additional information regarding the user's profile (address, age, phone #'s, etc.).
I decided that these attributes should be part of a different resource called RenterProfile (it's an app for renters), leaving nothing but the email address and password in the User resource. So I setup the appropriate controller, model, views and DB migration for this renter_profile resource. Once I had everything working (all the renter_profile fields within a single page/form, I then moved on to implementing a wizard for the renter_profile resource.
I followed Ryan's example pretty much verbatim simply swapping in renter_profile in place of user. I let my renter_profiles_controller perform the initial #create action with just a few basic fields (similar to creating the User with only the email and password). Then I created a renter_profile_steps controller (of course including the wicked gem same as Ryan's example). I placed the remaining attributes I wanted for the renter_profile into multiple form view files within the ~/views/renter_profile_steps directory.
The only hiccup I encountered was that
get "renter_profile/steps"
somehow ended up in my routes.rb file which messed everything up. Not sure how it ended up there (maybe wicked created it, but unlikely) or my coding partner did it without remembering... Regardless, with it removed, the renter_profile_steps_path began working correctly.You can see the actual code at: https://github.com/jvenator/wallet
We'll be taking the repository private in the next week or so as we start getting into more proprietary stuff, but for now feel free to have a look!
I think it's a little confusing that you're showing two forms; a user registration form and than two extra steps in a separate form, while really all three steps could go in one form, making it a lot more sustainable.
More important I was wondering how Wicked handles file uploads?
Is it possible to have a progress meeter like the jquery one you linked to?
Absolutely, you can do whatever you want in your steps views.
Hi guys,
wondering if anyone has tried this by submitting the form by AJAX?
I've got the first step that creates a new Project, then we redirect to the project_steps_path to go to the actual first step of the wizard. This works fine until we submit the form via AJAX where we just keep getting a 302 response Moved Temporarily, the Project does get created and I think the redirect to project_steps works, but instantly redirects again to the Project/index view.
I'm hoping to be able to submit by AJAX and in the response get the next views HTML
Has anyone else experienced this or something similar?
cheers
Chris
Muchas gracias por este tutorial lo implementare en el proyecto que entregare el dia viernes :)
Many thanks for this tutorial i implement it in the proyect i have to give in my job many thanks
Does this work in concert with a Twitter Bootstrap modal? I'd like to have my steps displayed inside a popup modal rather than render a new page. Can it be hacked to respond to JS requests?
Had a sneaky error on the last step with the re-direct. All the parameters updated my record properly, but got the following error: wrong number of arguments (1 for 0), _steps_controller.rb:57:in `redirect_to_finish_wizard'.
Using the Finish Wizard Path definition at: https://github.com/schneems/wicked it worked fine.
Thanks for a great tutorial!!
This is awesome, but what if I want the link_to to save the form data before it is clicked?
It seems wicked defaults to the form id to edit_put (maybe its a rails default?)
I cannot seem to over write this, but no matters since page per page i just want my link to save the data there, I thought I could call a submit action:
And then the java script on the page is:
$(document).ready(function() {
$('#my-link-check').click(function(event){
var form = document.getElementById("edit_put");
if(form!=null)
form.submit();
});
});
But this seems to not submit (does if have a breakpoint in firebug, odd) and then if that submit does work it doesnt goto the next page...
our "Save Document" buttons on these pages do work, and are just
submits. So not sure what critical piece I am missing to make this work.
Thank you ryan and keep it always up :-)
Hi everyone,
if you want to use another resource say "Products", you must
pass the product id in the ProductsController like this:
if @product.save
redirect_to product_step_path(:id => "first_step", :product_id => @ product.id)
else
...
And then you can find this product in the ProductStepsController:
product_steps_controller.rb:
def show
@product = Product.find(params[:product_id])
render_wizard
end
Hope it will help someone out there ;-)
Hi Guys,
Richard Schneeman is very nice. He posted the article how to implement wicked for another resource.
https://github.com/schneems/wicked/wiki/Building-Partial-Objects-Step-by-Step
Stay tuned :-)
Hi, very nice tutorial, I need to develop a very long form that will have many questions that will be optional based on the user inputs from a previous question for example:
Do you fever? Yes/No
(Questions appear in case user selected Yes)
Date it Started?
Temperature:
(Next question appears if user selected No)
Do you have allergies?
I will divide the form on several views but I would like some of the questions on the form only appearing if the users select the appropriate answer form the previous question.
Any ideas on how to implement this, thanks.
If I am using paperclip and have an upload option in first step.
Will the attachment be persistent in session/rack or I need to use some temporary table/model to store that file before the complete form is submitted ?
I developed a wizard using Angular JS. It is extremely simple and requires less code. It allows users to go back and change previous values. It's on github: https://github.com/bparanj/angular-wizard
Thanks for the screencast. I'm just wondering...is there a simple way to implement this while using devise? Right now, I'm thinking that I'd have to kind of hack the out my own create method in the UserRegistrationController that devise comes with.
In Firefox only.
http://localhost:3000/user_steps/%2E%2F%2E%2E%2F%2E%2E%2Fconfig%2Fdatabase%2Eyml
show database.yml
http://localhost:3000/user_steps/%2E%2F%2E%2E%2F%2E%2E%2F%2E%2E%2F%2E%2E%2Fetc%2Ffstab
show /etc/fstab
...
What's the best way to handle step-specific javascript code?
How can i perform step validation in the latest version 1.0.2 with rails 4. As
if: :on_categories_step?
is not working.Is there a reason the personal view uses
form_for @user
while the social view usesform_for current_user
? Since the controller sets @user to current_user, I suspect the views got created at different times and there's no real difference in this case. Though it seems like @user would be the better choice, since the controller can … control that value.