Kobus Post
Kobus Post

Reputation: 154

Dynamic Routes Rails 4, taken from db

Frustrating, I can't find an eligible solution for my problem.

In my Rails 4 app, I want to give my users the possibility to add their own custom post types to their sites. Like:

www.example.com/houses/address-1
www.example2.com/sports/baseball

Both would work, but only for the linked sites. Sports and houses would be the (RESTful) post types, taken from the db, added by users.

I have been struggling to find a elegant solution to accomplish this. I found http://codeconnoisseur.org/ramblings/creating-dynamic-routes-at-runtime-in-rails-4 but that feels kinda hacky and I'm not sure if reloading the routes works in production, I'm getting signals that it won't.

I'd say I have to use routes constraints http://guides.rubyonrails.org/routing.html#advanced-constraints but I don't have a clue how to approach this.

To be clear, I have no problem with the site setting stuff, the multi tenancy part of my app is fully functional (set in Middleware, so the current site is callable in the routes.rb file). My issue is with the (relative) routes, and how they could be dynamically set with db records.

Any pointers much appreciated.

Upvotes: 0

Views: 93

Answers (1)

sjagr
sjagr

Reputation: 16512

I think route constraints don't work for you because your domain is a variable here. Instead, you should be examining the request object.

In your ApplicationController, you could define a method that would be called before any action, like so:

class ApplicationController < ActionController::Base
  before_action :identify_site

  def identify_site
    @site = Site.where(:domain => request.host).first
  end
end

As you scale, you could use Redis for your domains so you're not making an expensive SQL call on each request.

Then you can just add the @site as a parameter to whatever call you're making. I'm assuming you're doing some sort of "Post" thing, so I'll write some boilerplate code:

class PostController < ApplicationController

  def show
    @post = Post.where(:site => @site, :type => params[:type], :id => params[:id])
  end

end

Just write your routes like any other regular resource.

Upvotes: 2

Related Questions