Rails 3.2友好的URL按日期路由

时间:2012-07-19 21:50:54

标签: ruby-on-rails ruby-on-rails-3 url-routing

我想实现具有以下功能的博客\新闻应用程序:

  1. 以root身份显示所有帖子:example.com/
  2. 显示所有回复某年的帖子:example.com/2012/
  3. 显示所有回答某些年份和月份的帖子:example.com/2012/07/
  4. 按日期和slug显示一些帖子:example.com/2012/07/slug-of-the-post
  5. 所以我为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<br/><br/>#{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<br/><br/>#{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=>#<Post id: 12, slug: "*", title: "*", content: "*", created_at: "2012-07-19 15:25:38", updated_at: "2012-07-19 15:25:38">}
      
    2. 当我去localhost/posts/2012/07/cut-test同样的事情发生时:

      No route matches {:controller=>"posts", :action=>"show", :year=>#<Post id: 12, slug: "*", title: "*", content: "*", created_at: "2012-07-19 15:25:38", updated_at: "2012-07-19 15:25:38">}
      
    3. 我觉得我有一些非常容易的东西,但我找不到它是什么。

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

2 个答案:

答案 0 :(得分:5)

问题在于帖子的路径助手使用情况为post_path(post),因为我在:as => :post中的参数化匹配中使用routes.rb时,第一个参数必须为年。< / p>

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

  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")

    如果名称正确,posts_pathposts_year_path("2012")posts_month_path("2012","12")也相同。

    我建议不要在该匹配项中同时使用:as => :post,也不要在模型文件中创建to_param,因为它可能会破坏您不期望的内容(对我而言为active_admin)。

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

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

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

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

答案 1 :(得分:0)

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