Ivan
Ivan

Reputation: 103879

Overriding the Rails router

This is a weird one I know. I'm trying to tie together two Rails applications, a v3 and a v2.3.5

I want them to share the same domain, and in order to do that without changing the URLs in the older app, I'm trying to find a way to override the Rails router.

I want the newer app living at the root of the domain, and the older one under several directories. For example:

/          => app1 # v3
/users     => app1
/employees => app2 # v2.3.5
/payrolls  => app2

So, since app1 lives at root and I'm using Passenger, I only have to create symlinks in the public folder of app1 to the public folder of app2, like so:

app1/public/employees => app2/public
app1/public/payrolls  => app2/public

And then I add RailsBaseURI /employees and RailsBaseURI /payrolls to Apache's config.

With that I can make old URLs of app2 work, but inside the app, the links point to a prefix. For example, /employees/1, /employees/employees/1, /payrolls/employees/1 all work, but links in the app point to /employees/employees/1 and /payrolls/employees/1 depending on which prefix I'm currently on.

So, I need to remove that prefix from the links so only the old URLs work.

I need to do this in order to release the newer app. In time I'll upgrade the older one to v3 and work directly on this issue, but right now any hack is ok just to make it work.

I don't expect a solution, but if you can point me in the right direction on where to look in Rails source, or maybe a simpler approach I'm not seeing, I'd be very grateful.

Upvotes: 2

Views: 298

Answers (2)

Ivan
Ivan

Reputation: 103879

Turns out it's pretty easy just by overriding url_for in the ApplicationHelper like so:

def url_for(options = {})
  original = super(options)
  # I tried this in order to improve performance:
  return original unless original.starts_with?('/employees/employees')
  original.gsub('/employees/employees', '/employees')
end

However, this caused intermittent errors in the app that I wasn't able to pinpoint. I suppose it's because of the performance hit.

So in the end I was forced to use a different domain for the newer apps.

Upvotes: 1

JB Juliano
JB Juliano

Reputation: 632

I'm not really sure if that's possible to use 2 different versions of rails on your routes, but another way to do that is using haproxy with 2 different servers.

# In haproxy.conf:

  frontend rails
    bind *:80
    acl rails2 hdr_host(end) -i employees.mydomain.com
    acl rails3 hdr_host(end) -i mydomain.com
    use_backend rails2_server if rails2
    use_backend rails3_server if rails3
    default_backend rails3_server

  backend rails2_server
    server myrails2_server 192.168.1.1:3000 check

  backend rails3_server
    server myrails3_server 192.168.1.1:3001 check

Then point your DNS A record of mydomain.com to your haproxy IP and point employees.mydomain.com to mydomain.com/employees.

To test it out, you can add the IP address of your haproxy server and mydomain.com to your /etc/hosts file

Upvotes: 0

Related Questions