render :action => :create only renders the template for the create action, it doesnt run the actual action, thats why the before filter doesnt get called. Rendering actions and rendering templates are very similar. So simliar that Im not sure why they arent merged into one.
Why are you going with one controller action and the if/elsif/else solution instead of just separating steps into different controller actions?
render :action => :create only renders the template for the create
action, it doesnt run the actual action, thats why the before filter
doesnt get called.
But if you look at the sample code, I did try to call the “Create” method as well as rendering its template:
elsif params["create"] # Called from the confirmation page where there will # be a button with name "create" create render :action => :create return
Why are you going with one controller action and the if/elsif/else
solution instead of just separating steps into different controller
The two controller actions are required because of 2 different security requirements.
The before_filter :require_user only applies to the “Create” controller action, and shouldn’t be a requirement for “Confirm” or for filling out a “New” entry.
From the Confirm action there is also a need to allow a “Back” step (via posting back the params again) and this also shouldn’t require a user constraint.
A poor-man’s solution is to manually call the “require_user” method at the top of the create function - but this doesn’t seem elegant and bypasses the whole point of the before_filter.
What I don’t understand is why doesn’t the *_filters run on every invocation of all Controller methods (including being called from within another method) and not just when it is called via the normal means of handling a routing request?
If you have other suggestions keep it rolling
But if you look at the sample code, I did try to call the "Create" method as well as rendering its template
No you didnt. render :action => :create is identical to render :template => 'mycontroller/create'. You might as well comment out the create action, its not getting called at all in your current code.
Im gonna suggest that you create one controller action for each step instead of trying to combine several steos into one action. To keep track of the object inbetween the requests you can store it in session.
def new @stuff = session[:stuff] || Stuff.new # session[:stuff] is used when the user clicks 'back' on the confirm page end
def confirm session[:stuff] = @stuff = Stuff.new(params[:stuff]) end
def create session[:stuff].save session[:stuff] = nil end
The way Im using sessions here isnt 100% by the book. Generally you dont want to store entire objects in session. One of the main reasons is that session objects can become incompatible with the code when you change something. The best way would be to actually store the temporary object in the database and then only store its ID in session. You can mark the temporary object as temporary with a boolean flag or have an entire table dedicated to temporary objects. The code above should be enough to get you started though.