Yo dawg, I heard you like…
Purely theoretical (obviously) case: you have existing php app and some legacy rails code that you refreshed a little bit and now someone asks you one simple question – why can’t you just put that code into that code and run it as one app? Sometimes you can reason, sometimes not. But let’s do it – I mean seriously – let’s create some kind of hybrid that will work transparently and silently for the user. Unleash your imagination and get ready for breaking every programming paradigm; treat it like a sport and get ready :).
Let’s ever get a little bit further, let’s create one rails app that will distribute its content for two different domains. Where do we start?
I assume you have some kind of working application already, in the end we want to have:
- domain.com – our main application written in php
- domain.com/superapp1 – rails app that is serving some part of content
- domain.com/superapp2 – same rails app that is serving another part of content
Moreover we want to create this whole structure in a way that it can be ran as separate apps in the future just in case.
First – get familiar with mod proxy as I’ll be using Apache here with with phusion passanger. I think the most reasonable approach is to handle two different sub-domains for serving content (plus admin namespace for backend).
So looking at our application it would look like:
- superapp1.rails.app – for serving content for ‘app1’. This url will be not directly accessible on production.
- superapp2.rails.app – same as above, for ‘app2’
- rails.app/admin – handling backend with restricted access
Be aware that I can’t provide where working example as solutions may vary quite a lot depending on structure of your existing applications and need, but I will give you some ideas if you will need to (theoretically) create that kind of hybrid someday.
Configure phussion passanger for your rails app, don’t forget to set
PassengerFriendlyErrorPages on and
RailsEnv "development" for now.
Now it’s time to start some proxy-action in your php app, setup in your virtual host config:
1 2 3 4 5
In your rails routes on the other hand you have to handle those sub-domains, after reading/watching this railscasts I ended up with:
1 2 3 4 5 6 7 8 9
1 2 3 4 5 6 7 8
After reloading apache cofiguration (
service apache2 reload) loading address /superapp1 from php app should bring on your brand new ror app.
Its not especially exciting and you may noticed some serious problems here:
you ended up with broken urls when trying to move deeper inside your proxy-ed app – as you need to provide proper urls
your assets are broken because you are working really on subdomain, but that can be easily fixed by adding to your apache conf:
ProxyPass /assets http://rails.app/assets
how can you serve diffirent part of content with same rails application depeding on those domains?
what about log in feature for your users?
Lets stard from fixing those urls, one way is to overload
url_for method from UrlHelper. I ended up with something like that:
1 2 3 4 5 6 7 8
1 2 3 4 5 6 7 8 9 10 11 12 13
Now when you call eg. articles_path or whatever you should end up with pretty proxy-ready url (that will be broken when you run your app as-it obviously).
I decided to filter content just by using CanCan (once again thank to Ryan) and setup access depending on current sub-domain in
ApplicationController (you can use
What’s left is authentication – how to setup backend access, log-in curret users – and that’s whole different subject. I will point three things here:
- you can work your way with php-memcached, dalli and cookies that are shared across your applications
- you can share existing database by setting up additional adapter in config/database.yml (then use establish_connection in your model and build up proper relation(s) onto existing database structure)
- in the end you probably would want to lock your domains they are accessible only from internal network(s), rewrite below should do it
1 2 3 4
Well, that’s it – very generall idea how it can be done, hope you liked this little piece of dark hackery ;–).