动态路由轨道4

时间:2016-02-20 05:30:19

标签: ruby-on-rails ruby ruby-on-rails-4 routes

我有一个网站,为每个用户提供他们自己的子域名,即cmcollin41.website.com。每个用户还可以为其子域网站创建自己的页面。因为我允许每个用户创建自己的页面,所以我需要为这些页面创建动态路由。我已经查看了关于SO的所有其他问题,但我还没有找到答案来帮助我解决这个问题。

我目前的大部分工作都来自此博文:http://codeconnoisseur.org/ramblings/creating-dynamic-routes-at-runtime-in-rails-4

我的主要问题是我根据子域设置每个用户,我需要在某处访问request.subdomain(在routes.rb或模型甚至lib文件夹中),以便我可以通过子域进行迭代用户创建路线的页面。

这是我的代码:

class User < ActiveRecord::Base
has_many :pages

def self.load
  Walkaboutio::Application.routes.draw do
    #This doesn't work. I know you can't access the request in the model. 
    #I've been trying for a while to try and figure out how and where to set
    #the user via the request.subdomain so I can create the route for each of 
    #the users pages.
    @account = User.find_by(subdomain: request.subdomain)
    @account.pages.all.each do |pg|
      get "/#{pg.name}", to: "pages#pages", defaults: { id: pg.id }
    end
  end
end

end


class ApplicationController < ActionController::Base

protect_from_forgery with: :exception

before_action :set_account

private

  def set_account
    @account ||= User.find_by(subdomain: request.subdomain)
  end

  helper_method :set_account

end


class PagesController < ApplicationController

  def pages
    @page = Page.find(params[:id])
    @bio = @account.bio
  end

end

routes.rb

class SubdomainConstraint
  def self.matches?(request)
    request.subdomain.present? && request.subdomain != 'www'
  end
end


Rails.application.routes.draw do

  constraints SubdomainConstraint do 
    root to: 'pages#show', as: :portfolio
    #This is where I load the routes
    User.load
    get '/users/:id/setup', to: 'users#setup', as: :setup
    resources :analytics
    resources :calendars
    resources :events
    resources :users
  end

  root to: 'pages#index', as: :marketing

  get '/auth/:provider/callback', to: 'sessions#create'
  get '/auth/failure', to: 'sessions#auth_fail'
  get '/sign_out', to: 'sessions#destroy', as: :sign_out

  get 'contact', to: 'events#new', as: 'contact'
  post 'contact', to: 'events#create'

end

提前感谢您的帮助。

1 个答案:

答案 0 :(得分:0)

在多租户应用中使用数据驱动路由生成的一个缺点是,在所有意图和目的中,应用中定义的路由是全局到整个应用。

在这种情况下我要做的是,让所有路由都被构建,但是在控制器中将查询约束到page.id和account.id并返回“not found”或者在这种情况下你需要做什么。像这样:

在您的网页控制器中,利用您在发出set_page时已设置的@account:

class PagesController < ApplicationController
  before_action :set_page, only: [:show, :edit, :update, :destroy]

  private 

  def set_page
    unless @page = Page.where(account_id: @acount.id, id: params[:id]).first
      raise ActiveRecord::RecordNotFound
    end
  end

end