Search code examples
ruby-on-railsbefore-filter

in Rails : Retrieve user input from a form that isn't associated with a Model, use the result within the controller


Here's a simplified version of what I'm trying to do :

  1. Before any other actions are performed, present the user with a form to retrieve a string.
  2. Input the string, and then redirect to the default controller action (e.g. index). The string only needs to exist, no other validations are necessary.
  3. The string must be available (as an instance variable?) to all the actions in this controller.

I'm very new with Rails, but this doesn't seem like it ought to be exceedingly hard, so I'm feeling kind of dumb.

What I've tried : I have a before_filter redirecting to a private method that looks like

def check_string
  if @string
    return true
  else
    get_string
  end
end

the get_string method looks like

def get_string
  if params[:string]
    respond_to do |format|
      format.html {redirect_to(accounts_url)} # authenticate.html.erb
    end
  end

  respond_to do |format|
    format.html {render :action =>"get_string"} # get_string.html.erb
  end
end

This fails because i have two render or redirect calls in the same action. I can take out that first respond_to, of course, but what happens is that the controller gets trapped in the get_string method. I can more or less see why that's happening, but I don't know how to fix it and break out. I need to be able to show one form (View), get and then do something with the input string, and then proceed as normal.

The get_string.html.erb file looks like

<h1>Enter a string</h1>
<% form_tag('/accounts/get_string') do %>
<%= password_field_tag(:string, params[:string])%>
<%= submit_tag('Ok')%>
<% end %>

I'll be thankful for any help!

EDIT

Thanks for the replies...
@Laurie Young : You are right, I was misunderstanding. For some reason I had it in my head that the instance of any given controller invoked by a user would persist throughout their session, and that some of the Rails magic was in tracking objects associated with each user session. I can see why that doesn't make a whole lot of sense in retrospect, and why my attempt to use an instance variable (which I'd thought would persist) won't work. Thanks to you as well :)


Solution

  • Part of the problem is that you aren't setting @string. You don't really need the before_filter for this at all, and should just be able to use:

    def get_string
      @string = params[:string] || session[:string] 
      respond_to do |format|
        if @string  
          format.html {redirect_to(accounts_url)} # authenticate.html.erb
        else 
          format.html {render :action =>"get_string"} # get_string.html.erb
        end
      end
    end
    

    If you want the @string variable to be available for all actions, you will need to store it in the session.