Daniel Sindrestean
Daniel Sindrestean

Reputation: 1193

Correct way of writing a conditional filter in Rails controller

For writing a conditional filter in a controller in rails, the recommended way seems to be using a lambda like this:

before_action :authenticate_user, unless: -> { !Rails.env.production? && ENV['DISABLE_LOGIN'] == 'true' }

While the above seems to be the correct way of doing it, the following situation seems to also work well in the case of my example:

before_action :authenticate_user unless !Rails.env.production? && ENV['DISABLE_LOGIN'] == 'true'

What I would like to understand is what are the differences between the 2 approaches and if the second approach can yield an undesired outcome in certain scenarios.

Upvotes: 2

Views: 624

Answers (1)

3limin4t0r
3limin4t0r

Reputation: 21110

Let me start of by adding some parentheses and some newlines to better display the difference between the two.

before_action(
  :authenticate_user,
  unless: -> { !Rails.env.production? && ENV['DISABLE_LOGIN'] == 'true' }
)

# vs

unless !Rails.env.production? && ENV['DISABLE_LOGIN'] == 'true'
  before_action(:authenticate_user)
end

The first version, with the unless as part of the options, always defines the before_action :authenticate_user. The unless lambda is executed for each request and authenticate_user only called if the lambda resolves into a falsy value.

The second version makes the check controller is defined. Based on those checks the before_action :authenticated is either defined or not defined. Note that the checks made in this version cannot use params since it uses the controller class context, only instances of a controller class have access to web-request.


Since your condition only uses environment variables and doesn't any web-request data, the second option is the faster one. However if you change the environment variables while the server is running you would need to reload the controller class (by restarting the server).

If you use the first option you could change the environment variables, and have them effect the controller without restart. Due to the check being made for each request.

Upvotes: 2

Related Questions