也许你已经看过/读过Railscast/Asciicast about subdomains in Rails 3。我希望您在找不到父项(在本文中为“blog”)时询问有关如何实现应用程序行为的最佳实践。让我解释一下。
blog1.example.com/articles # it's normal situation
example.com/articles # abnormal situation.
在第二个例子中没有要查找的博客,但文章的路线仍然可用。我知道,我可以使用这样的东西......
def rescue_action(exception)
case exception
when ActiveRecord::RecordNotFound
return redirect_to blogs_path, :status => :moved_permanently
end
super
end
......但它是“Rails方式”吗?对此有什么想法/评论吗?
答案 0 :(得分:0)
我在这种情况下所做的是限制基于子域或没有子域的路由。在这种情况下,您可以轻松地拥有仅适用于子域的路由,如果有人尝试访问没有子域的相同路由,则会导致路由错误(404)。
例如:
Backend::Application.routes.draw do
constraints AppDomainRoutes.new do
# signup paths
get "/signup" => "accounts#new", as: "signup"
post "/signup" => "accounts#create", as: "signup"
# root
root to: "accounts#new"
end
constraints AccountDomainRoutes.new do
# password reset paths
get "/reset_password/:password_reset_token" => "reset_passwords#edit", as: "reset_user_password"
put "/reset_password/:password_reset_token" => "reset_passwords#update", as: "reset_user_password"
# websites
resources :websites
# root
root to: "websites#new"
end
# request password reset paths
get "/reset_password" => "reset_passwords#new", as: "reset_password_request"
post "/reset_password" => "reset_passwords#create", as: "reset_password_request"
# login paths
get "/login" => "sessions#new", as: "login"
post "/login" => "sessions#create", as: "login"
# logout paths
get "/logout" => "sessions#destroy", as: "logout"
delete "/logout" => "sessions#destroy", as: "logout"
end
然后在lib / routes中:
class AppDomainRoutes
def matches?(request)
request.subdomain.blank? || request.subdomain == "www"
end
end
class AccountDomainRoutes
def matches?(request)
request.subdomain.present? && request.subdomain != "www"
end
end
现在,/signup
只能从主应用程序域 www.mydomain.com或mydomain.com 访问,而/websites/new
只能从 *访问.mydomain .COM 。但是为方便起见,/login
仍然可以在两种情况下访问。
显然,当invalid.mydomain.com
实际上不是数据库中的帐户时,这无法解决访问invalid
的问题。
为此,您返回application_controller.rb
并在那里处理重定向,如下所示:
class ApplicationController < ActionController::Base
protect_from_forgery
before_filter :redirect_unknown_account
private
# returns current subdomain (account.subdomain) or nil
def account_subdomain
@account_subdomain ||= request.subdomain if request.subdomain.present? && request.subdomain != "www"
end
def current_account
@current_account ||= Account.find_by_username(account_subdomain) if account_subdomain
end
def redirect_unknown_account
if account_subdomain && ! current_account
redirect_to signup_url(host: app_domain), alert: "This account does not exist."
end
end
def account_domain
@account_domain ||= "#{current_account.username}.#{app_domain}" if current_account
end
def app_domain
@app_domain ||= "mydomain.com"
end
end