Rails sessions current practices
Use the database for sessions instead of the cookie-based default, which shouldn't be used to store highly confidential information
Create the session table with
rake db:sessions:create
Run the migration
rake db:migrate
Make sure you also tell rails to use ActiveRecord to manage your sessions too.
Rails 3
config/initializers/session_store.rb:
Rails.application.config.session_store :active_record_store
Rails 2
config/environment.rb:
config.action_controller.session_store = :active_record_store
Generate current session's user id into the form in rails
Try
<%= form_for(@income, :html =>{:class => "form "}) do |f| %>
<%= label_tag :title %>
<%= text_field :title, params[:title] %>
<%= label_tag :amount %>
<%= number_field :amount, params[:amount] %>
<br>
<% if current_user %>
User ID:<%= current_user.id %>
User Name: <%= current_user.user_name %>
<%= f.hidden_field :user_id, value: current_user.id%>
<% end %>
<%= submit_tag "Submit" %>
<% end %>
Rails: Is that safe to store data in session?
It depends of your session store.
By default use cookies as a session store so by default it's not safe it's pretty easy to change the content of a cookie.
So you could either :
- change your session store in
config/initializers/session_store.rb and use an activerecord store (so it will be store in the db) or a memcache store. There's also plenty of plugins on github letting you use redis, mongodb, ... as sessions stores - store this information in your db and have a before_filter in your application_controller accessing the cookie to get the current user id and getting the whole user object in a variable @current_user
Storing User Data in Session - Standard Practice
Option 2 is the way to go.
Option 1 is "No" because your session data will be out of sync with the database as soon as the user information gets updated. Say for example you store those ten fields in the session upon user login, and later in the application the user updates one of those ten fields, now the session data is out of sync with the database. You could define a function that updates the session data when one of the attributes changes but I think this adds unnecessary extra complexity to the application.
Option 3, I cannot think of anything that replaces the session for this requirement. There are other ways you could implement the session logic but they would just be your version of already provided(by Rails) implementation of session.
Finding the current user in the session in Rails
You have made a fundamental logic error here.
Controller instance variables only exist in the scope of a single request. When a request hits your rails application it matches the request to your routes. The routes give a controller / action combination and Rails uses this information to instantiate a new instance of the controller class and call the correct method on it.
This code does not actually in any way persist anything across requests:
def current_user
@current_user ||= User.find_by(id: session[:user_id])
end
Rather it uses conditional assignment to prevent running User.find_by
repeatedly (and thus querying the database) in the same request.
This is a technique known as memoization.
The session on the other hand persists between requests since it is stored in a cookie that is passed back and forth between the client and server.
Rails: How to store data in session?
To store something in a session you can do:
session[:answer] = "some answer"
Then you can call the answer with:
session[:answer]
Or you could use HTML5 localstorage:
<script>
localStorage.setItem("essay", "text");
localStorage.getItem("essay"); // => "text"
</script>
How to store session id and expiration time to database?
Creating sessions in db:
Rails sessions current practices
Sweeping sessions:
http://guides.rubyonrails.org/security.html#session-expiry
Getting most recent paths visited across sessions in Rails app
I think that Redis would be ideally suited to this. It's one of the NoSQL key-value store db's, but its support for the value part being an ordered list, queue, etc. should make it easy to store unique urls in a FIFO list as they are visited, limit the size of that list (discard urls at the 'old' end of the list), and retrieve the most recent N urls to pass to your view. Your list should stay small enough that it would all stay in memory and be very fast. You might be able to do this with memcached or mongo or another one as well; I think it would be best though if the solution kept the stored values in memory.
If you aren't already using redis (or similar), it might seem like overkill to set it up and maintain just for this feature. But you can make it pay for itself by also using it for caching, background job processing (Resque / Sidekiq), and probably other things in your app.
rails 3, heroku, how to use sessions
You do not have to change anything for Heroku. By default, Rails sessions are stored in an encrypted cookie, so there is no server-side configuration necessary.
However, a cookie can only store 4,096 bytes of data. If you are storing a lot of data in the session (which generally is not recommended), you may overflow the cookie. In this case, you may wish to set up ActiveRecord or Memcached-based cookies. Both of these are easy to do, and are not really Heroku-specific issues. If you need help with this, you can always ask another StackOverflow question. For now, it's not worrying about until you hit the limit.
Some rough code to store and read your answers in the session, assuming Question and Answer are ActiveRecord models:
def store_answer(question, answer)
session[:answers] ||= {}
session[:answers][question.id] = answer.id
end
def read_answer(question)
Answer.find(session[:answers][question.id])
end
Related Topics
Converting Camel Case to Underscore Case in Ruby
Nokogiri Installation Fails -Libxml2 Is Missing
How to Extract Url Parameters from a Url With Ruby or Rails
What's Different Between Each and Collect Method in Ruby
Group Hashes by Keys and Sum the Values
When to Use 'Self.Foo' Instead of 'Foo' in Ruby Methods
Actioncontroller::Unknownformat
Why Are Gems Installed in a Directory With a Different Ruby Version Than I'M Running
Creating Matrix With 'Array.New(N, Array.New)'
What Does the "Map" Method Do in Ruby
Sort Hash by Key, Return Hash in Ruby
What's the Best Way to Use Soap With Ruby
Accepts_Nested_Attributes_For With Belongs_To Polymorphic