Ruby on Rails中创建新的资源时,确认没有路由重叠
-
13-09-2019 - |
题
我有一个RESTful设置用于使用文本固定链接作为ID的资源在一个Rails应用程序的路由。
在此外,还有一些特殊命名的路线以及与所述指定的资源e.g重叠:
# bunch of special URLs for one off views to be exposed, not RESTful
map.connect '/products/specials', :controller => 'products', :action => 'specials'
map.connect '/products/new-in-stock', :controller => 'products', :action => 'new_in_stock'
# the real resource where the products are exposed at
map.resources :products
在Product
模型是使用 permalink_fu 基于所述名称生成永久链接,并ProductsController
进行查找的永久场访问时。这一切工作正常。
然而,在数据库中创建新Product
记录时,我想验证所产生的固定链接做的不可以有一个特殊的URL重叠。
如果用户试图创建一个名为specials
或new-in-stock
甚至像new
或edit
正常的Rails REST的资源的方法的产品,我想控制器查找路由配置中,模型对象上设置错误,未通过验证的新记录的,而不是将其保存。
我可以硬编码称为非法固定链接名称的列表,但它似乎杂乱这样做的。我宁愿挂钩到路由来自动执行。
(变更,以保护无辜并使其更容易回答控制器和型号名称,实际的设置比这个例子中更复杂的)
解决方案
那么,这个工作,但我不知道它是多么可爱。主要的问题是混合控制器/路由逻辑到模型中。基本上,你可以在模型中添加自定义的验证,以检查它。这是使用无证路由方法,所以我不知道它会如何稳定地向前发展。任何人有更好的想法?
class Product < ActiveRecord::Base
#... other logic and stuff here...
validate :generated_permalink_is_not_reserved
def generated_permalink_is_not_reserved
create_unique_permalink # permalink_fu method to set up permalink
#TODO feels really ugly having controller/routing logic in the model. Maybe extract this out and inject it somehow so the model doesn't depend on routing
unless ActionController::Routing::Routes.recognize_path("/products/#{permalink}", :method => :get) == {:controller => 'products', :id => permalink, :action => 'show'}
errors.add(:name, "is reserved")
end
end
end
其他提示
您可以使用本来不会存在的路线。这样,如果有人选择保留字作为标题或没有它不会使任何区别。
map.product_view '/product_view/:permalink', :controller => 'products', :action => 'view'
而在你的观点:
product_view_path(:permalink => @product.permalink)
这是一个更好的做法来管理的URI明确自己对于这样的原因,并避免意外暴露的路线,你不想。
不隶属于 StackOverflow