Dan Rubio
Dan Rubio

Reputation: 4907

Where am I supposed to define a constraint for routes.rb?

I am following the rails guides for advanced constraints Advanced Constraints. Here is the code:

class BlacklistConstraint
  def initialize
    @ips = Blacklist.retrieve_ips
  end

  def matches?(request)
    @ips.include?(request.remote_ip)
  end
end

Rails.application.routes.draw do
  get '*path', to: 'blacklist#index',
    constraints: BlacklistConstraint.new
end

The guides fail to mention where the BlacklistConstraint is supposed to be defined or whether it follows naming conventions. I've tried to follow this example for my own use but I keep getting an UninitialiezedConstantError: Can someone help me out? So far I;ve defined my constraint class in the 1routes.rbfile itself and in thelib` directory. Both methods did not work.

Upvotes: 1

Views: 871

Answers (1)

user273895
user273895

Reputation: 654

An expected place for this class would be lib/constraints.

http://api.rubyonrails.org/classes/ActionDispatch/Routing/Mapper/Scoping.html#method-i-constraints-label-Dynamic+request+matching

Update: Based on the helpful comments, I'll try to make this a complete answer.

According to the docs your constraint class should be placed under lib/constraints, but since the lib directory is not eager loaded by rails you can enable it by adding this line to config/application.rb

config.eager_load_paths << Rails.root.join('lib')

Now rails will try to load the lib/constraints/blacklist_constraint.rb file and would expect it to be correctly namespaced, so wrap that class in a Module (which also makes it cleaner because you might have more constraints in the future)

module Constraints
  class BlacklistConstraint
    def initialize
      @ips = Blacklist.retrieve_ips
    end

    def matches?(request)
      @ips.include?(request.remote_ip)
    end
  end
end

and reference Constraints::BlacklistConstraint in routes.rb.

Upvotes: 3

Related Questions