Rails before_action not called on reload

757 views Asked by At

I have a Rails application (5.2.4.1) deployed in a subdirectory on a WordPress site. My controllers calls a before_action method to authenticate users

class ClientsController < ApplicationController
  before_action :authenticate unless ENV["RAILS_ENV"] == "development"
  before_action :set_agent
  before_action :set_client, only: [:show, :edit, :update, :destroy]

that calls a method in ApplicationController to redirect if the user does not have a cookie from another site on the domain

class ApplicationController < ActionController::Base
  protect_from_forgery with: :exception

  private
  def authenticate
    logger.info("Authenticate method called") # outputs on first load, not subsequent
    if request.cookies.collect{|c| c.grep(/cookiename/)}.blank?
      redirect_to 'https://example.com', status: :moved_permanently and return
    end
  end

If I go to a private browser (so no cookies) and try to access the controller I am redirected as expected.

If I put the same URL, the authenticate method is not called. The controller renders the action. I put a logging statement in the authenticate method and it is not called on the further page loads.

Am I doing something wrong? I expect before_action methods to be called each page load. The other two (set_agent and set_client) are presumably not called either but since they set instance variables based on route parameters it doesn't cause an issue.

2

There are 2 answers

0
mrturtle On

The issue turned out to be how I was checking for the absence of a cookie.

request.cookies.collect{|c| c.grep(/cookiename/)}.blank?

would return an array of empty arrays (eg. [[], [], []] ) on page loads where there were cookies and [[], [], []].blank? evaluated to false.

This it not what I wanted.

I switched to checking cookies by key (which should have happened in the first place) and this fixed the issue.

I do not know why I did not see the logger output on subsequent loads. I assume I just missed it.

1
nkkumawat On

you should use the correct syntax of the before_action

class ClientsController < ApplicationController
  before_action :authenticate, :unless => ENV["RAILS_ENV"] == "development"
  .
  .
  .

Some more examples are

before_action :verify_authenticity_token_with_exception, :only => [:update_data], :unless => :ignore_csrf?
before_filter :authenticate_user!, :except => [:some_method]