我有一个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重叠。

如果用户试图创建一个名为specialsnew-in-stock甚至像newedit正常的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明确自己对于这样的原因,并避免意外暴露的路线,你不想。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top