herited_resources-缺少父模型的最佳实践



也许您已经看到/阅读了Railscast/Acicast关于Rails3中子域的内容。我希望您了解在找不到父级(本文中为"博客"(时如何实现应用程序行为的最佳实践。让我解释一下。

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 

但这是"铁轨之路"吗?对此有什么想法/意见吗?

在这种情况下,我所做的是基于子域或无子域来限制路由。在这种情况下,你可以很容易地拥有只在子域上工作的路由,如果有人试图在没有子域的情况下访问同一路由,就会导致路由错误(404(。

例如:

路线.rb

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:

app_domain_routes.rb

class AppDomainRoutes
  def matches?(request)
    request.subdomain.blank? || request.subdomain == "www"
  end
end

account_domain_routes.rb

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实际上不是数据库中的帐户时,这并不能解决访问invalid.mydomain.com的问题。

为此,您返回application_controller.rb并在那里处理重定向,如下所示:

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

相关内容

  • 没有找到相关文章