Get constraint based url using url_for based on mounted engine
Asked Answered
I

3

11

Is there any way that i can make url_for to return the url based on the request.host during action dispatch routing ?

mount Collaborate::Engine => '/apps/collaborate', :constraints => {:host => 'example.com' }
mount Collaborate::Engine => '/apps/worktogether'

Example:

When the user is on example.com host

collaborate_path => /apps/collaborate

When the user is on any other host

collaborate_path => /apps/worktogether

After a lot of research, i realize that RouteSet class has named_routes which does not consider the constraints to return the url.

I've tried overriding @set in action_dispatch/routing/route_set.rb to pickup from rails application but dint work as expected

@search_set = Rails.application.routes.set.routes.select{|x| x.defaults[:host] == options[:host] }[0]
@set = @search_set unless @search_set.blank?
Inverter answered 7/12, 2015 at 11:17 Comment(0)
E
7

Remove .com in your example

mount Collaborate::Engine => '/apps/collaborate', :constraints => {:host => 'examplesite' }
mount Collaborate::Engine => '/apps/worktogether'

Should just work

If you need a more advanced constraint, make your own constraint:

class CustomConstraint
  def initialize
    # Things you need for initialization
  end

  def matches?(request)
    # Do your thing here with the request object
    # http://guides.rubyonrails.org/action_controller_overview.html#the-request-object
    request.host == "example"
  end
end

Rails.application.routes.draw do
  get 'foo', to: 'bar#baz',
    constraints: CustomConstraint.new
end

You can also specify constraints as a lambda:

Rails.application.routes.draw do
  get 'foo', to: 'foo#bar',
    constraints: lambda { |request| request.remote_ip == '127.0.0.1' }
end

source: http://guides.rubyonrails.org/routing.html#advanced-constraints

Elm answered 17/12, 2015 at 13:15 Comment(0)
H
2

As for as my concern if you handle it at middleware level then it would be good. This is what my assumption.

Add this line in config/application.rb

config.middleware.insert_before ActionDispatch::ParamsParser, "SelectiveStack"

Add a middleware in app directory with middleware directory as a Convention

app/middleware/selective_stack.rb

class SelectiveStack
  def initialize(app)
    @app = app
  end

  def call(env)
    debugger
    if env["SERVER_NAME"] == "example.com"
      "/apps/collaborate"
    else
      "/apps/worktogether"
    end
  end


end

Hope this will solve your issue.!!!

Hekate answered 17/12, 2015 at 12:29 Comment(0)
C
1

Alright, here's a shot in the dark; maybe you've tried it already or maybe I'm really missing something. On the surface, it really looks like you're just trying to override a path helper method for apps. So why not set up an override in the application_helper.rb? Something like:

module ApplicationHelper
  def collaborate_path
    if request.domain == "example.com"
      "/apps/collaborate"
    else
      "/apps/worktogether"
    end
  end
end
Catalyst answered 14/12, 2015 at 20:55 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.