Froze rails gems
[depot.git] / vendor / rails / railties / doc / guides / source / actioncontroller_basics / session.txt
1 == Session ==
2
3 Your application has a session for each user in which you can store small amounts of data that will be persisted between requests. The session is only available in the controller and the view and can use one of a number of different storage mechanisms:
4
5 * CookieStore - Stores everything on the client.
6 * DRbStore - Stores the data on a DRb server.
7 * MemCacheStore - Stores the data in a memcache.
8 * ActiveRecordStore - Stores the data in a database using Active Record.
9
10 All session stores use a cookie - this is required and Rails does not allow any part of the session to be passed in any other way (e.g. you can't use the query string to pass a session ID) because of security concerns (it's easier to hijack a session when the ID is part of the URL).
11
12 Most stores use a cookie to store the session ID which is then used to look up the session data on the server. The default and recommended store, the CookieStore, does not store session data on the server, but in the cookie itself. The data is cryptographically signed to make it tamper-proof, but it is not encrypted, so anyone with access to it can read its contents but not edit it (Rails will not accept it if it has been edited). It can only store about 4kB of data - much less than the others - but this is usually enough. Storing large amounts of data is discouraged no matter which session store your application uses. You should especially avoid storing complex objects (anything other than basic Ruby objects, the most common example being model instances) in the session, as the server might not be able to reassemble them between requests, which will result in an error. The CookieStore has the added advantage that it does not require any setting up beforehand - Rails will generate a "secret key" which will be used to sign the cookie when you create the application.
13
14 Read more about session storage in the link:../security.html[Security Guide].
15
16 If you need a different session storage mechanism, you can change it in the `config/environment.rb` file:
17
18 [source, ruby]
19 ------------------------------------------
20 # Set to one of [:active_record_store, :drb_store, :mem_cache_store, :cookie_store]
21 config.action_controller.session_store = :active_record_store
22 ------------------------------------------
23
24 === Disabling the Session ===
25
26 Sometimes you don't need a session. In this case, you can turn it off to avoid the unnecessary overhead. To do this, use the `session` class method in your controller:
27
28 [source, ruby]
29 ------------------------------------------
30 class ApplicationController < ActionController::Base
31 session :off
32 end
33 ------------------------------------------
34
35 You can also turn the session on or off for a single controller:
36
37 [source, ruby]
38 ------------------------------------------
39 # The session is turned off by default in ApplicationController, but we
40 # want to turn it on for log in/out.
41 class LoginsController < ActionController::Base
42 session :on
43 end
44 ------------------------------------------
45
46 Or even for specified actions:
47
48 [source, ruby]
49 ------------------------------------------
50 class ProductsController < ActionController::Base
51 session :on, :only => [:create, :update]
52 end
53 ------------------------------------------
54
55 === Accessing the Session ===
56
57 In your controller you can access the session through the `session` instance method.
58
59 NOTE: There are two `session` methods, the class and the instance method. The class method which is described above is used to turn the session on and off while the instance method described below is used to access session values.
60
61 Session values are stored using key/value pairs like a hash:
62
63 [source, ruby]
64 ------------------------------------------
65 class ApplicationController < ActionController::Base
66
67 private
68
69 # Finds the User with the ID stored in the session with the key :current_user_id
70 # This is a common way to handle user login in a Rails application; logging in sets the
71 # session value and logging out removes it.
72 def current_user
73 @_current_user ||= session[:current_user_id] && User.find(session[:current_user_id])
74 end
75
76 end
77 ------------------------------------------
78
79 To store something in the session, just assign it to the key like a hash:
80
81 [source, ruby]
82 ------------------------------------------
83 class LoginsController < ApplicationController
84
85 # "Create" a login, aka "log the user in"
86 def create
87 if user = User.authenticate(params[:username, params[:password])
88 # Save the user ID in the session so it can be used in subsequent requests
89 session[:current_user_id] = user.id
90 redirect_to root_url
91 end
92 end
93
94 end
95 ------------------------------------------
96
97 To remove something from the session, assign that key to be `nil`:
98
99 [source, ruby]
100 ------------------------------------------
101 class LoginsController < ApplicationController
102
103 # "Delete" a login, aka "log the user out"
104 def destroy
105 # Remove the user id from the session
106 session[:current_user_id] = nil
107 redirect_to root_url
108 end
109
110 end
111 ------------------------------------------
112
113 To reset the entire session, use `reset_session`.
114
115 === The flash ===
116
117 The flash is a special part of the session which is cleared with each request. This means that values stored there will only be available in the next request, which is useful for storing error messages etc. It is accessed in much the same way as the session, like a hash. Let's use the act of logging out as an example. The controller can send a message which will be displayed to the user on the next request:
118
119 [source, ruby]
120 ------------------------------------------
121 class LoginsController < ApplicationController
122
123 def destroy
124 session[:current_user_id] = nil
125 flash[:notice] = "You have successfully logged out"
126 redirect_to root_url
127 end
128
129 end
130 ------------------------------------------
131
132 The `destroy` action redirects to the application's `root_url`, where the message will be displayed. Note that it's entirely up to the next action to decide what, if anything, it will do with what the previous action put in the flash. It's conventional to display eventual errors or notices from the flash in the application's layout:
133
134 ------------------------------------------
135 <html>
136 <!-- <head/> -->
137 <body>
138 <% if flash[:notice] -%>
139 <p class="notice"><%= flash[:notice] %></p>
140 <% end -%>
141 <% if flash[:error] -%>
142 <p class="error"><%= flash[:error] %></p>
143 <% end -%>
144 <!-- more content -->
145 </body>
146 </html>
147 ------------------------------------------
148
149 This way, if an action sets an error or a notice message, the layout will display it automatically.
150
151 If you want a flash value to be carried over to another request, use the `keep` method:
152
153 [source, ruby]
154 ------------------------------------------
155 class MainController < ApplicationController
156
157 # Let's say this action corresponds to root_url, but you want all requests here to be redirected to
158 # UsersController#index. If an action sets the flash and redirects here, the values would normally be
159 # lost when another redirect happens, but you can use keep to make it persist for another request.
160 def index
161 flash.keep # Will persist all flash values. You can also use a key to keep only that value: flash.keep(:notice)
162 redirect_to users_url
163 end
164
165 end
166 ------------------------------------------
167
168 ==== +flash.now+ ====
169
170 By default, adding values to the flash will make them available to the next request, but sometimes you may want to access those values in the same request. For example, if the `create` action fails to save a resource and you render the `new` template directly, that's not going to result in a new request, but you may still want to display a message using the flash. To do this, you can use `flash.now` in the same way you use the normal `flash`:
171
172 [source, ruby]
173 ------------------------------------------
174 class ClientsController < ApplicationController
175
176 def create
177 @client = Client.new(params[:client])
178 if @client.save
179 # ...
180 else
181 flash.now[:error] = "Could not save client"
182 render :action => "new"
183 end
184 end
185
186 end
187 ------------------------------------------