我有一个网站,为每个用户提供他们自己的子域名,即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
提前感谢您的帮助。
答案 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