4

Our websites should allow to show different contents related to the given url .. something like a multisite in wordpress where we have one installation and serve the content according to the url.

as it is necessary to have the routes in the correct language I want to use a "dynamic route" approach to serve the right content. My problem is now that I dont find a way how to serve the proper routes in routes.rb if they are dynamic.

How can I "access" or "pass" the request object into any method inside the routes.rb file

f.e. like this

routes.rb

  Frontend::Application.routes.draw do
    DynamicRouter.load request
  end

app/models/dynamic_router.rb

class DynamicRouter
  def self.load request
    current_site = Site.find_by_host(request.host)
    Frontend::Application.routes.draw do
      current_site.routes do |route|
        get "#{route.match}", to: "#{route.to}"
      end
    end
  end
end

this doesnt work because request is undefined in routes.rb

Mik
  • 1,705
  • 1
  • 14
  • 26
  • so, basically, you want to support every route? – André Barbosa Feb 18 '14 at 13:39
  • I want to have dynamic routes for each website.. f.e. if for one of our sites i want to call /category/:id and for another one it should be /category/:slug it should be able to do it if I could just pass the request object from routes.rb into the model method, I already know how I can do the rest – Mik Feb 18 '14 at 13:40
  • /category/:id and /category/:slug are the same route. the only difference is that on the first the dynamic part will be stored in params[:id] and on the second is params[:slug] – André Barbosa Feb 18 '14 at 13:44
  • yes sure.. but imagine you have www.site1.com and www.site2.com ... both are served from one codebase .... in routes.rb I want to find out from which site the request comes and serve the right routes for this site – Mik Feb 18 '14 at 13:46
  • so, based on the domain, you want to use a different controller? – André Barbosa Feb 18 '14 at 13:49
  • based on the domain I want to serve CategoryController/show either from category/:id or categoria/:id --- f.e. if you conssider that we have different languages in different domains – Mik Feb 18 '14 at 13:55
  • let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/47764/discussion-between-mik-and-andre-barbosa) – Mik Feb 18 '14 at 13:56
  • could it be something like: Category.translations { |t| get "#{t}/:id", to: 'category#show' } ? – André Barbosa Feb 18 '14 at 14:01

2 Answers2

3

To answer your question: How can I "access" or "pass" the request object into any method inside the routes.rb file Obtain it as ENV object from rack middleware.See code below

# lib/dynamicrouterrequest.rb
require 'rack'
class DynamicRouterRequest
  def initialize(app)
    @app = app
  end
  def call(env)
    request=Rack::Request.new(env)
    ENV["OBJ_REQUEST"]=request.inspect.to_s
    @app.call(env)
  end
end

Grab it again in routes

# routes.rb
Frontend::Application.routes.draw do
  request=ENV["OBJ_REQUEST"]
  DynamicRouter.load request
end
ivanxuu
  • 842
  • 9
  • 10
James Mwaiponya
  • 77
  • 1
  • 10
1

A possible soluction is to create the default rules on routes.rb and add a rack middleware that can transform a path according to the domain

# routes.rb
get '/category/:id', :to => 'categories#show'

In the middleware you can transform a path like 'categoria/:id' to '/category/:id' if the domain matches '.es', before the application hits the router layer.

More on rack middleware: http://guides.rubyonrails.org/rails_on_rack.html

André Barbosa
  • 518
  • 4
  • 17