Rails 3.2友好的URL按日期路由

我想实现具有以下能力的blog \ news应用程序:

  1. 显示root上的所有post: example.com/
  2. 显示所有回答某年的post: example.com/2012/
  3. 显示所有回答某些年份和月份的post: example.com/2012/07/
  4. 显示一些post的日期和slug: example.com/2012/07/slug-of-the-post

所以我为routes.rb文件创建了一个模型:

 # GET /?page=1 root :to => "posts#index" match "/posts" => redirect("/") match "/posts/" => redirect("/") # Get /posts/2012/?page=1 match "/posts/:year", :to => "posts#index", :constraints => { :year => /\d{4}/ } # Get /posts/2012/07/?page=1 match "/posts/:year/:month", :to => "posts#index", :constraints => { :year => /\d{4}/, :month => /\d{1,2}/ } # Get /posts/2012/07/slug-of-the-post match "/posts/:year/:month/:slug", :to => "posts#show", :as => :post, :constraints => { :year => /\d{4}/, :month => /\d{1,2}/, :slug => /[a-z0-9\-]+/ } 

因此,我应该在index操作中使用params并在show动作中通过slug发布(检查日期是否为corect是一个选项):

 # GET /posts?page=1 def index #render :text => "posts#index

#{params.to_s}" @posts = Post.order('created_at DESC').page(params[:page]) # sould be more complicated in future end # GET /posts/2012/07/19/slug def show #render :text => "posts#show

#{params.to_s}" @post = Post.find_by_slug(params[:slug]) end

我还必须为我的模型实现to_param

 def to_param "#{created_at.year}/#{created_at.month}/#{slug}" end 

这就是我从api / guides / SO中彻夜搜索的所有知识。

但问题是奇怪的事情一直在发生在我身上作为铁杆的新手:

  1. 当我转到localhost/ ,应用程序断开并说它已调用show动作但数据库中的第一个对象已被收到:year(sic!):

     No route matches {:controller=>"posts", :action=>"show", :year=>#} 
  2. 当我去localhost/posts/2012/07/cut-test时会发生同样的事情:

     No route matches {:controller=>"posts", :action=>"show", :year=>#} 

我觉得我有一些非常容易的东西,但我找不到它是什么。

无论如何,这篇文章在解决后会有所帮助,因为只有针对url的解决方案只有没有日期和相似但没有用的问题。

问题在于post的路径助手用法为post_path(post) ,因为我使用的第一个参数必须是年份:as => :postroutes.rb中的参数化匹配中routes.rb

尽管如此,要使整个解决方案明确,还需要采取一些措施来使所有工作正常运行:

  1. 您必须为每个匹配添加正确的路径助手名称,例如

     # Get /posts/2012/07/slug-of-the-post match "/posts/:year/:month/:slug", <...>, :as => :post_date 

    现在,您可以在post_date_path("2012","12","end-of-the-world-is-near")中使用post_date_path("2012","12","end-of-the-world-is-near")

    如果正确命名,则posts_pathposts_year_path("2012")posts_month_path("2012","12")

    我建议不要同时使用:as => :post在该匹配中:as => :post ,也不在模型文件中创建to_param ,因为它可以破坏你不期望的东西(对于我来说是active_admin )。

  2. 控制器文件posts-controller.rb应填充需要提取的post,并在slug之前检查日期的正确性。 然而,在这种状态下它是可以的,什么都不打破。

  3. 模型文件posts.rb应以适当的格式填写年份和月份,例如:

     def year created_at.year end def month created_at.strftime("%m") end 

    我已经注意到,确实没有to_param方法。

这是你的完整routes.rb文件? 听起来你可能有一个先前的resources :posts条目,基本上匹配/posts/:id 。 此外,我发布的路径文件中没有任何内容可以导致从根路径重定向到post,所以它必须是其他内容。