Grouping routes in block to perform contextual actions

11 views
Skip to first unread message

Robert Pawlas

unread,
Oct 4, 2021, 11:20:59 AM10/4/21
to Roda
Hello,
I am trying to "group" routes to perform some actions (i.e. checking permissions) before matching them, but this should be applied only for few of them in given path. I found that always method might be helpful achieving this, but I am unsure if it is safe to use.

Consider following code:

class App < Roda
  route do |r|
    r.on 'foo' do
      r.always do
        # performing permission check for 2 routes only in /foo subpath
        raise NotPermittedError unless user.admin?

        # GET /foo/bar
        r.get 'bar'do
        end

        # GET /foo/baz
        r.get 'baz' do
        end
      end

      # GET /foo/faz
      r.get 'faz' do
      end
    end
  end
end

Is it ok to use it this way? Or maybe is there any existing plugin that already handles this? (checked it , but haven't found)

Jeremy Evans

unread,
Oct 6, 2021, 5:22:55 PM10/6/21
to ruby...@googlegroups.com
r.always will always match.  You shouldn't be able to call it directly as it is private.  You can use r.on without arguments without arguments for the same effect.

Note that probably isn't what you want.  Because r.always or r.on without arguments will always yield to the block, execution will not continue past that.  So your r.get 'faz' code will never be reached.

A better approach in your case would be to have r.get 'faz' first, then the permission check, then the other two routes.  However, with more complicated routes, that's not always possible.  Having a separate segment for the paths that need different permissions works well for that if it is possible.  Otherwise, you can do the permission check separately in both the bar and baz routes.

Thanks,
Jeremy

Robert Pawlas

unread,
Oct 7, 2021, 8:50:10 AM10/7/21
to Roda
Got it. Thanks for all the hints and wide explanation. 
Reply all
Reply to author
Forward
0 new messages