目前,如果你想添加一个约束,有许多方法可以做到,但正如我现在所看到的,你只能包含一个被调用的权威方法。 E.g。
Class Subdomain
# Possible other `def`s here, but it's self.matches? that gets called.
def self.matches?( request )
# Typical subdomain check here
request.subdomain.present? && request.subdomain != "www"
end
end
上述方法存在的问题是它没有处理以www为前缀的路由,即admin和www.admin是不可分割的。可以添加更多逻辑,但如果在一组静态子域(例如admin,support和api)上需要这些逻辑,则您当前需要创建SubdomainAdmin,SubdomainSupport等....
这可以通过routes.rb
中的正则表达式解决:
管理员
:constraints => { :subdomain => /(www.)?admin/ }
API
:constraints => { :subdomain => /(www.)?api/ }
如果请求比这更复杂,那么事情变得棘手。那么有没有办法在用于约束的类中添加单个方法?
基本上,如何实现以下目标?它甚至可能吗?什么是使用白名单子域名的最佳方法?
E.g。
Class Subdomain
def self.admin_constraint( request )
# Some logic specifically for admin, possible calls to a shared method above.
# We could check splits `request.subdomain.split(".")[ 1 ].blank?` to see if things are prefixed with "www" etc....
end
def self.api_constraint( request )
# Some logic specifically for api, possibly calls to a shared method above.
# We could check splits `request.subdomain.split(".")[ 1 ].blank?` to see if things are prefixed with "www" etc....
end
def self.matches?( request )
# Catch for normal requests.
end
end
我们现在可以通过以下方式特别调用约束:
:constraints => Subdomain.admin_constraints
所有通用约束如下:
:constraints => Subdomain
这在Rails 4.0.3中是否可行?
答案 0 :(得分:0)
路由器将在您通过路由的任何对象上调用#matches?(request)
方法。在
:constraints => Subdomain
您正在为Subdomain
Class对象提供路由。但是,您也可以传递一个实例,您可以通过参数进行配置。如,
Class Subdomain
def initialize(pattern)
@pattern = pattern
end
def matches?(request)
request.subdomain.present? && @pattern ~= request.subdomain
end
end
# routes.rb
namespace :admin, constraints: Subdomain.new(/(www.)?admin/) do
# your admin routes here.
end
注意:我没有验证代码是否有效,我只是把它写在了我的头顶,所以考虑更多的伪代码而不是实现准备。
此外,您可以在Use custom Routing Constraints to limit access to Rails Routes via Warden查看此技术的示例,其中包含更多详细信息。