Ye Olde Form, Sessions and Params hash type questions

Hi,

Forgive me if this sounds like a commonly asked question, but I've
searched high and low and read all the books and I'm still struggling.

I'm trying to park the Data from an HTML form into a session and then
retrieve it. Maybe I'm trying to do the wrong, I dont know. The idea is
that they fill in the form, go to a confirmation screen, then go to a
final form where it's submitted to the database. I'm not even sure if
thats the right logic. I think I need to park the data in a session. But
I cant see how.

All I can get in a session is one piece of data and I dont know how to
reference it.

Here's what I have:

This is in my Controller

    def confirm_form
      @checkin = params[:checkin]
      @checkout = params[:checkout]
      @nights = params[:nights]
    end

and this is small snippet of my form:

            <% form_tag(:action => "confirm_form") do %>
            <p>checkin:<%= text_field_tag("checkin") %></p>
            and so on...
            <%= submit_tag("next") %>

which works and can be retrieved on the next page like this:

         Checkin: <%= @checkin %> <br>
         Checkout <%= @checkout %> <br>
         Nights: <%= @nights %> <br>

But how do I put that data in a session to be retrieved when ever I
want?

I'm struggling here, this is confusing the heck out of me.

Maybe I should be just parking it all in a DB. i just dont know.

Thank for any help at all.

Alex.

session[:checkin] = @checkin

Ryan Bigg wrote:

session[:checkin] = @checkin

This is whats confusing me. I cant figure out the logic to put all the
form fields into the session, and then retrieve that session.

If I make the method:

  def confirm_form
        session[:checkin] = @checkin
   end

How do I then get that data back out?

I'll do some more searching...

Thanks, Alex

Once you do

session[:checkin] = @checkin

then session[:checkin] is a reference to the same object that @checkin was. So if you have a name attribute on @checkin

@checkin.name

you can do

session[:checkin].name

or better

@checkin = session[:checkin]

to get all of it out at once.

Peace,
Phillip

@checkin = session[:checkin]

to get all of it out at once.

Peace,
Phillip

Cool, OK - somethings not right then...

So the action for my form_tag is:

    <% form_tag(:action => "confirm_form3") do %>

Which calls this method in my controller:

   def confirm_form
        session[:checkin] = @checkin
    end

Then I have a view called "confirm_form.html.erb" onto which I put:

    <%= @checkin = session[:checkin] %>

And that should render the values?

If I do: <%= session[:checkin].checkout %>

I get the "The error occurred while evaluating nil.checkout" error.

Which makes me think that it doesnt know about the 'checkin' session?

In my form I put:

          <% form_tag(:action => "confirm_form") do %>
          <p>checkin:<%= text_field_tag("checkout") %></p>
          <%= submit_tag("next") %>

I think I must be missing something vital here.

Thanks for any help.

Alex.

    <% form_tag(:action => "confirm_form3") do %>

Ignore that typo where I put _form3. :slight_smile:

It’s your

def confirm_form
session[:checkin] = @checkin
end

That’s buggered.

You should be referencing it as params[:checkin], not @checkin.

Whoops, that’s what I suggested :slight_smile: What I meant was you were definining @checkin as params[:checkin] before, so now it should be:

session[:checkin] = params[:checkin]

Ryan Bigg wrote:

Whoops, that's what I suggested :slight_smile: What I meant was you were definining
@checkin as params[:checkin] before, so now it should be:

session[:checkin] = params[:checkin]

Ok, excellent. I think I'm getting somewhere:

So I need to set a session per form-field?

Like this:

  def confirm_form
      session[:formStore1] = params[:checkin]
      session[:formStore2] = params[:checkout]
      session[:formStore3] = params[:nights]
  end

which I then display like this:

   Checkin: <%= @checkin = session[:formStore1] %> <br>
   Checkout <%= @checkout = session[:formStore2] %> <br>
   Nights: <%= @nights = session[:formStore3]%> <br>

That seems long winded to me...

But works.

Thanks, Alex

You could just do session[:thingo] = params and then reference session[:thingo][:checkin]

Storing it on a cookie so when the user comes back they see it? Why not store it as a record on the table and then get it the next time the user logs in?

Ryan Bigg wrote:

You could just do session[:thingo] = params and then reference
session[:thingo][:checkin]

Hmm... Ok, so I made my method like this:

  def confirm_form
      session[:formStore1] = params
  end

With the view the same it now squirts out the entire cookie hash:

commitnextauthenticity_token35663ebb22fd497d1ab91470957fa140d8a09f24actionconfirm_formnights5checkin2controllerbooking_formcheckout4
How do I reference the value I need?

This doesnt seem to do that:

   <%= @checkin = session[:formStore1] %>

Which will just get the entire cookie.

Cheers, Alex

what does <%= debug session.inspect %> give?

Ryan Bigg wrote:

what does <%= debug session.inspect %> give?

An enormous string that goes on and one. here's a snippet:

Session:0x18dbcb4 @data={:formStore=>\"2\",
:formStore1=>{\"commit\"=>\"next\",
\"authenticity_token\"=>\"35663ebb22fd497d1ab91470957fa140d8a09f24\",
\"action\"=>\"confirm_form\", \"nights\"=>\"5\", \"checkin\"=>\"2\",
\"controller\"=>\"booking_form\", \"checkout\"=>\"4\"}, :checkin=>\"8\",
:formStore2=>\"b\", :csrf_id=>\"67653f2742e8057138188392d7777064\",
:formStore3=>\"c\", \"flash\"=>{}},
@dbprot=[#<CGI::Session::CookieStore:0x18db764 @data={:formStore=>\"2\",
:formStore1=>{\"commit\"=>\"next\",
\"authenticity_token\"=>\"35663ebb22fd497d1ab91470957fa140d8a09f24\",
\"action\"=>\"confirm_form\", \"nights...

Al

You are using the output ruby delimiter <%= . The best you can hope for here is to get a true because the assignment of @checkin = session[:checkin] succeeded. I guess I missed the code, but you will probably want to do your

@checkin = session[:checkin]

in the controller action that is going to be rendering your view. Then in your view, you will have the form tag/helper that renders the form. At that point, you will use @checkin to get the data out, whether it be a form_for or form_tag. I might be misunderstanding, but it sounds like you are expecting Rails to automatically render the contents of @checkin when you pull it out of session. It doesn't quite work like that.

Hope that helps.

Phillip

I think you might have mistaken my meaning. I use session as a general purpose hash all the time. I store everything in it, from orders to other hashes to strings and integers (I can hear some people hissing and booing now *grin*). What I meant by "it doesn't work that way" was that you can't pull something out of session and have Rails magically use it. For instance, if I store form fields into session, I might do it something like this:

def create
  @my_obj = Obj.new(params)
  <do some things with @my_obj if you need to>
  session[:my_obj] = @my_obj
end

Now, when we get to the next step in the process, something like this will happen

def step_two
  # get my_obj out of session so the view has access to it
  @my_obj = session[:my_obj]
  # render whatever you need to
end

And let's say the view is using a standard form_tag

form_tag :action => :step_two_save
  text_field_tag :some_value, @my_obj.some_value
  text_field_tag :some_other_value, @my_obj.some_other_value
end

You'd have to reference the specific attribute of @my_obj in your form. Rails isn't going to just know what to do with that object. Now, if you're using form_for, I might be mistaken as I haven't used that much (or at all).

At least, this is how I do it. Maybe I'm making it more difficult than it needs to be...

Peace,
Phillip

Hey

def create
  @my_obj = Obj.new(params)

...snip

At least, this is how I do it. Maybe I'm making it more difficult
than it needs to be...

Peace,
Phillip

Hmm, maybe :slight_smile:

I dont know. I'm still utterly confused about how this works.

I think I need to create my array and store that array in the session.
Which makes sense. But for the life of me I cant figure out how to do
that. I can create Arrays and hashes and pull data out of them in Ruby,
but when it comes to Rails and using sessions it just all falls apart. I
cant make head-nor-tail of it.

Oh well. :frowning:

Thanks, alex

Hi Alex,

You should be able to do this

session[:my_array] = Array.new

session[:my_array] << an_element

copy_of_element = session[:my_array][0]

Does that not work?

Peace,
Phillip

H Phillip,

I'm probably doing something wrong somewhere...

The only way I've managed to get the values in and out is like this:

Here's my original 'index.htm.erb' form code

  <% form_tag(:action => "confirm_form") do %>
  <p>checkin:<%= text_field_tag("checkin") %></p>
  <p>checkout:<%= text_field_tag("checkout") %></p>
  <p>nights:<%= text_field_tag("nights") %></p>
  <%= submit_tag("next") %>
  <% end %>

And here's the controller code from 'booking_form_controller.rb'

def confirm_form
      session[:formStore1] = params[:checkin]
      session[:formStore2] = params[:checkout]
      session[:formStore3] = params[:nights]
  end

and then my 'confirm_form.html.erb' view code looks like this:

  Checkin: <%= @checkin = session[:formStore1] %> <br>
  Checkout: <%= @checkout = session[:formStore2] %> <br>
  Nights: <%= @nights = session[:formStore3]%> <br>

Which did all seem rather verbose.

I'd assumed I could pass the key value pair into a hash stored in the
Session, then reference the key to pull out the value. I think I'm
probably just struggling with the syntax a little - maybe I'm not
understanding how the the form results are being passed into my
confirm_form method. I'm not sure really :slight_smile:

But what I have works, just doesnt seem right or very nice to me. I
couldnt get an joy trying to pass the key and values from the from into
an array as you described. It kept spitting out the key and value. :confused:

Thanks, Alex

Phillip Koebbe wrote:

And here's the controller code from 'booking_form_controller.rb'

def confirm_form
      session[:formStore1] = params[:checkin]
      session[:formStore2] = params[:checkout]
      session[:formStore3] = params[:nights]
  end

try this

def confirm_form
  session[:formStore] = HashWithIndifferentAccess.new if session[:formStore].nil?

  session[:formStore].merge!(params)
end

and then my 'confirm_form.html.erb' view code looks like this:

  Checkin: <%= @checkin = session[:formStore1] %> <br>
  Checkout: <%= @checkout = session[:formStore2] %> <br>
  Nights: <%= @nights = session[:formStore3]%> <br>

and this

Checkin: <%= session[:formStore][:checkin] %> <br />
Checkout: <%= session[:formStore][:checkout] %> <br />
Nights: <%= session[:formStore][:nights] %> <br />

But now that I see what you're trying to do, you don't really need to shove that into session. If all you want to do is redisplay what the user entered, you can access params over in the confirm_form.html.erb view without bothering with session. Unless you have redirected or something. If you redirect, you will need to use session.

Peace,
Phillip