Rails 4 个子域,绑定到控制器

Rails 4 subdomains, tied to controller

感谢有你们作为资源!我认为这应该是一个简单的问题,但尚未能够通过搜索找到简单的答案,任何 help/guidance 将不胜感激!! 我有一个按以下方式设置的 "subdomain" 控制器:

get 'subdomain/:store' => 'subdomain#index'
get 'subdomain/:store/products' => 'subdomain#product_index'
get 'subdomain/:store/products/:id' => 'subdomain#products_show'

如您所见,子域控制器将请求与 Store ID 进行匹配,并且还可以获得具有 Store ID 的所有关联产品的索引。我想以某种方式将这些请求中的每一个转换为子域而不是路径。每个 Store 都有一个 "subdomain" 属性(在下面的示例中,其中一个 Store 记录的子域值为 "nike")。

例如

host.com/subdomain/nike => nike.host.com
host.com/subdomain/nike/products => nike.host.com/products
host.com/subdomain/nike/products/5 => nike.host.com/products/5

注意控制器 "subdomain" 已从路径中删除。有什么帮助吗?我研究了诸如公寓之类的宝石,但它们看起来太复杂了。也是 subdomain-fu,但它看起来已经过时 Rails 4. 想法?谢谢!

为此,您可以添加路由约束。

将文件添加到 lib/subdomain_required.rb

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

然后,在您的 routes.rb 中,您可以将您的路由包含在一个约束块中,有点像这样:

constraints(SubdomainRequired) do
  get '/' => 'subdomain#index'
  get '/products' => 'subdomain#product_index'
  get '/products/:id' => 'subdomain#products_show'
end

现在最后一步是根据子域加载商店,这可以使用 before_action 这样的

来完成
class SubdomainController < ActionController::Base
  before_action :ensure_store!

  def index
   @products = current_store.products.all
  end

  def ensure_store!
    @store ||= Store.find_by subdomain: request.subdomain
    head(:not_found) if @store.nil?
    @store
  end

  def current_store
    @store
  end
end

现在任何你想获取商店的地方,你都可以使用 current_store 辅助方法。

希望对您有所帮助