How to Access Cookies from Applicationcontroller (Rails)

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



Leave a reply



Submit