How to access cookies from ApplicationController (Rails)
This might work for you:
class ApplicationController
before_filter :handle_cookies
def handle_cookies
# Do whatever it is you want to do with your cookies
end
end
The before_filter
method will call whatever subroutine you indicate (:handle_cookies
) after cookies
has been compiled into a hash. Adding this code to your application controller will mean that all the other controllers inherit it and will perform the same function.
How to set cookies in ApplicationController?
What do you mean by setting cookie in application controller? You would set cookie in browser corresponding to some controller action. If you want to set the cookie for all actions then you may consider using a before filter and apply that filter to all your controller actions.
You can set and delete cookies as shown below:
cookies[:key] = {
:value => 'a yummy cookie',
:expires => 1.year.from_now,
:domain => 'example.com'
}
cookies.delete(:key, :domain => 'example.com')
Please note that if you specify a :domain when setting a cookie, you must also specify the domain when deleting the cookie.
e.g. cookies[:user_name] = "david"
Ruby on Rails - Read Cookie value after page load
Cookies are a client side feature. You server can only read cookies when there is a request, i.e in your controller action.
The only way to read a cookie after the page has loaded is with Javascript: document.cookie
https://developer.mozilla.org/en-US/docs/Web/API/Document/cookie
http://clubmate.fi/setting-and-reading-cookies-with-javascript/
Rails reading cookies returns a string instead of an object
Cookies are string-based. So storing a non-String value to cookies needs to be serialised when setting the value, and then needs to be unserialised when reading the value. See cookies docs here.
However, normally, you don't serialize database records because it might be stale already (not up-to-date to actual values in the database) once you get the ActiveRecord
object back through deserialisation. Which is why I would recommend doing something below.
app/controllers/sellers_controller.rb:
class SellersController < ApplicationController
before_action :set_seller, only: [:show]
before_action :set_seller_first_shop, only: [:show]
before_action :set_cookies, only: [:show]
def show
@listings = Listing.where(shop: @shop).paginate(page: params[:page])
end
private
def set_seller
@seller = Seller.find(params[:id])
end
def set_seller_first_shop
@shop = @seller.shops.first
end
def set_cookies
cookies.signed[:user_id] = current_user.id
cookies.signed[:seller_id] = @seller.id
cookies.signed[:shop_id] = @shop.id
end
end
app/controllers/titles_controller.rb
class TitlesController < ApplicationController
before_action :set_from_cookies, only: [:index]
def index
@titles = Title.last
end
private
def set_from_cookies
@shop = Shop.find(cookies.signed[:shop_id])
@seller = Seller.find(cookies.signed[:seller_id])
@user = User.find(cookies.signed[:user_id])
end
end
Ruby on Rails - Can't set cookies in some actions
I don't think, you can do this with POST/PUT/PATCH requests. When you are doing redirect_to
, rails sends 302 Found
reponse with location
specified in parameter of redirect_to
in your case cookies[:target_path]
or root_path
.
Browser then understends it should do redirect and sends GET request to URL specified in location
header. You cannot nor should try to tell it to do POST/PUT/PATCH requests - these types of requests usually also require some kind of data (eg submitted form) that goes along with the request. You lost all of these data during redirect to login page anyway.
What I am trying to say - use these redirects only for GET requests. It will not work for POST/PUT/PATCH.
How do I get a signed cookie from the request?
Implement a constraint as indicated in the Ruby on Rails guide, and use this to access your cookies:
cookies = ActionDispatch::Cookies::CookieJar.build(request, request.cookies)
You can now access your signed or encrypted cookies as usual:
cookies.signed[:user_id]
Check the cookies/session in the routes.rb file
I think you should use a different approach here. For example, you can map root path always to same action and put all logic into that action:
class UsersController < ApplicationController
def index
redirect_to welcome_path and return unless logged_in?
... # rest of your code here
end
end
NOTE: Assuming logged_in?
is a method that loads current user from session or returns nil.
Probably it's a good idea to move this kind of logic into a before_filter
(in Rails4 before_action
):
class UsersController < ApplicationController
before_filter :require_login
def index
end
private
def require_login
redirect_to welcome_path unless logged_in?
end
end
If most of your application (controllers scope) depends on a logged user, move it to the ApplicationController
(filter will run on each request). You can skip it using skip_before_filter :require_login
in the particular cases without this requirement.
By the way, if you want to achieve it via your routes, you can play with constraints
(doc here). Example code:
YourApp::Application.routes.draw do
root 'users#index', constraints: lambda { |request| request.session['user_id'].present? }
root 'welcome#index'
end
More ideas in this question: How can I redirect a user's home (root) path based on their role using Devise?
Where can I use cookies in Ruby on Rails
If you want to set something up prior to each request you should use a before_filter
.
class MyController << ApplicationController
before_filter :cookie_setup
def cookie_setup
a = cookies[:a]
.. whatever you want to do with 'a'
end
end
Related Topics
Does Ruby Have Any Number Formatting Classes
How to Include Blank Field in Select_Tag
Check to See If an Array Is Already Sorted
Rails 4.1 Activerecord::Relation Is No More Like Array
Inherit Class-Level Instance Variables in Ruby
How to Extract a Single Character (As a String) from a Larger String in Ruby
How to Print Stdout Immediately
Automatically Open a File as Binary with Ruby
Ruby String Split with Terminal Strings Empty
Ruby: Could Not Find a Temporary Directory
Skip/Disable Force_Ssl for Particular Controller in Rails
How to Split Routes.Rb into Smaller Files
In Ruby, How to Get Instance Variables in a Hash Instead of an Array
Why Does Ruby Builder::Xmlmarkup Add Inspect Tag to Xml
How to Make a Class Whose Constructor Looks Like the Constructor of a Built-In Class