Rails 3.2 友好的 url 日期路由 [英] Rails 3.2 friendly url routing by date

查看:38
本文介绍了Rails 3.2 友好的 url 日期路由的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I want to implement blog\news application with ability to:

  1. 在根目录下显示所有帖子:example.com/
  2. 显示某年回答的所有帖子:example.com/2012/
  3. 显示回答某个年份和月份的所有帖子:example.com/2012/07/
  4. 按日期和 slug 显示一些帖子:example.com/2012/07/slug-of-the-post

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

So I have created a mockup for routes.rb file:

# 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 动作中使用参数,然后在 show 动作中通过 slug 获得帖子(检查日期是否正确是一个选项):

So I should work with params in index action and just get post by slug in show action (checking whether date is corect is an option):

# 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:

Also I have to implement to_param for my model:

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

这就是我在 api/guides/SO 中通宵搜索所学到的全部.

This is all I have learned from all night long searching in api/guides/SO.

但问题是奇怪的事情不断发生对我来说是 Rails 的新手:

But the problem is strange things keep happenning for me as new to rails:

  1. 当我转到 localhost/ 时,应用程序中断并说它已调用 show 操作,但数据库中的第一个对象已被接收为 :year (原文如此!):

  1. When I go to localhost/, the app breaks and says that it had invoked show action but first object in database had been recieved as :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">}

  • 当我去 localhost/posts/2012/07/cut-test 时,同样的事情发生了:

  • When I go to localhost/posts/2012/07/cut-test same thing happens:

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

  • 我觉得有一些很简单的东西我没有做过,但我找不到它是什么.

    I feel that there is something very easy that I haven't made, but I can't find what is it.

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

    Anyway, this post will be helpful when it is solved, because there are solutions only for just slugs in url without date and similar but not useful questions.

    推荐答案

    问题出在作为 post_path(post) 的 post 路径助手使用中,​​因为自从我使用 以来,第一个参数必须是年份:as =>:post in parametrized 匹配 routes.rb.

    The problem was in post's path helper usage as post_path(post), because first parameter must be year since I use :as => :post in parametrized match in routes.rb.

    然而,为了使整个解决方案清晰,这里需要采取一些措施来使所有工作正常进行:

    Nevertheless, to make the entire solution clear here are some actions needed to make that all work proper:

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

    1. You must add proper path helpers names for each match, e.g.

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

    Now you can use post_date_path("2012","12","end-of-the-world-is-near") in views.

    同样适用于 posts_pathposts_year_path("2012")posts_month_path("2012","12"),如果命名正确.

    Same for posts_path, posts_year_path("2012"), posts_month_path("2012","12") if properly named.

    我建议不要同时使用 :as =>:post 在那个匹配中,也不在模型文件中创建 to_param 因为它会破坏你不期望的东西(就像 active_admin 对我来说).

    I advice not to use neither :as => :post in that match nor creating to_param in model file as it can break something you don't expect (as active_admin for me).

    控制器文件 posts-controller.rb 应该填充需要在 slug 之前提取和检查日期正确性的帖子.尽管如此,在这种状态下它是可以的并且不会破坏任何东西.

    Controller file posts-controller.rb should be filled with posts that needed extraction and checking of date's correctness before slug. Nevertheless in this state it is OK and breaks nothing.

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

    Model file posts.rb should be filled with year and month extraciton in proper format, e.g.:

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

    正如我已经注意到的那样,没有真正需要的 to_param 方法.

    There is no to_param method really needed as I've noticed already.

    这篇关于Rails 3.2 友好的 url 日期路由的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

    查看全文
    登录 关闭
    扫码关注1秒登录
    发送“验证码”获取 | 15天全站免登陆