2

I'm trying to learn Roda and am having a bit of trouble moving into a style of separating out routes into their own files. I got the simple app from the Roda README running and am working on that as a base.

I am trying to use the multi_route plugin as well. So far, this is my setup:

config.ru

require 'rack/unreloader'
Unreloader = Rack::Unreloader.new { Greeter }
require 'roda'
Unreloader.require './backend.rb'
run Unreloader

backend.rb

require 'roda'
# Class Roda app
class Greeter < Roda
  puts 'hey'
  plugin :multi_route

  puts 'hey hey hey'
  route(&:multi_route)
end

Dir['./routes/*.rb'].each { |f| require f }

index.rb

Greeter.route '/' do |r|
  r.redirect 'hello'
end

hello.rb

Greeter.route '/hello' do |r|
  r.on 'hello' do
    puts 'hello'
    @greeting = 'helloooooooo'

    r.get 'world' do
      @greeting = 'hola'
      "#{@greeting} world!"
    end

    r.is do
      r.get do
        "#{@greeting}!"
      end

      r.post do
        puts "Someone said #{@greeting}!"
        r.redirect
      end
    end
  end
end

So, now when I do my rackup config.ru and go to localhost:9292 in my browser, I get a blank page and 404s in the console. What is out of place? I suspect I'm not using multi_route correctly, but I'm not sure.

Community
  • 1
  • 1
mwdowns
  • 75
  • 1
  • 2
  • 8

2 Answers2

2

You can use multi_run plugin:

routes/foo.rb

module Routes
  class Foo < Roda
    route do |r|
      r.get do
        "hello foo"
      end
    end
  end
end

routes/bar.rb

module Routes
  class Bar < Roda
    route do |r|
      r.get do
        "hello bar"
      end
    end
  end
end

config.ru

require "roda"

Dir['routes/*.rb'].each { |f| require_relative f }

class App < Roda
  plugin :multi_run # Allow to group many "r.run" in one call

  run 'foo', Routes::Foo # match /foo
  run 'bar', Routes::Bar # match /bar

  # Same as
  # route do |r| 
  #   r.multi_run
  # end
  route(&:multi_run)
end

run App.freeze.app

For more alternatives:

1

It's a bit old, but maybe it will be useful for someone later on.

For Roda, forward slashes are significant. In your example, Greeter.route '/hello' do |r| matches localhost:9292//hello, and not localhost:9292/hello.

You probably want the following:

Greeter.route do |r|
  r.redirect 'hello'
end

And also this. That nested r.on 'hello' do meant that that branch of the tree only matched localhost:9292/hello/hello and localhost:9292/hello/hello/world, that is probably not what you wanted.

Greeter.route 'hello' do |r|
  puts 'hello'
  @greeting = 'helloooooooo'

  r.get 'world' do
    @greeting = 'hola'
    "#{@greeting} world!"
  end

  r.is do
    r.get do
      "#{@greeting}!"
    end

    r.post do
      puts "Someone said #{@greeting}!"
      r.redirect
    end
  end
end
Maciej Szlosarczyk
  • 789
  • 2
  • 7
  • 21