Where to put constraint classes in Rails project
H

2

22

Just curious about the best practices for Rails in where I put a custom constraints class that's used as a constraint in config/routes.rb. Seems like Rails.root/lib is where all user classes go. Is that appropriate for this? Should I be creating a directory inside for constraints? 2 empty directories exist there now, assets and tasks. Are there conventions for this?

Hanselka answered 23/10, 2012 at 18:53 Comment(0)
A
25

lib/ would be the appropriate place. If you want to make it cleaner, put it in lib/constraint/authenticated.rb and define your constraints like so

module Constraint
  class Authenticated
    def matches?(request)
      # stuff
    end
  end
end

and in your routes.rb

constraints Constraint::Authenticated.new do
  match 'account' => 'account#index'
end
Acetaldehyde answered 23/10, 2012 at 19:0 Comment(2)
Didn't know you could specify constraints that way. Didn't see that in the Rails Guide, guides.rubyonrails.org/routing.html.Hanselka
I have basically the same exact set up - except I get a NameError: uninitialized constant Constraint error. When I remove the module, and just reference MyConstraint.new (with no namespace), it works. Why does wrapping this in a module throw such an error? I really want that namespace ><Limit
T
12

This is strange that the guide says nothing about that path, but lib/constraints is even listed in the API (ActionDispatch::Routing::Mapper::Scoping):

You are able to move this logic out into a class if it is too complex for routes. This class must have a matches? method defined on it which either returns true if the user should be given access to that route, or false if the user should not.

class Iphone
  def self.matches?(request)
    request.env["HTTP_USER_AGENT"] =~ /iPhone/
  end
end

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

Tamp answered 23/5, 2013 at 16:47 Comment(1)
While the API suggests lib/constraints, I think app/constraints is a more appropriate place because the latter is loaded automatically but the former is not. This is just my practice, though.Fries

© 2022 - 2024 — McMap. All rights reserved.