Rails 3.2友好的URL按日期路由
我想实现具有以下能力的blog \ news应用程序:
- 显示root上的所有post:
example.com/
- 显示所有回答某年的post:
example.com/2012/
- 显示所有回答某些年份和月份的post:
example.com/2012/07/
- 显示一些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中彻夜搜索的所有知识。
但问题是奇怪的事情一直在发生在我身上作为铁杆的新手:
-
当我转到
localhost/
,应用程序断开并说它已调用show
动作但数据库中的第一个对象已被收到:year(sic!):No route matches {:controller=>"posts", :action=>"show", :year=>#}
-
当我去
localhost/posts/2012/07/cut-test
时会发生同样的事情:No route matches {:controller=>"posts", :action=>"show", :year=>#}
我觉得我有一些非常容易的东西,但我找不到它是什么。
无论如何,这篇文章在解决后会有所帮助,因为只有针对url的解决方案只有没有日期和相似但没有用的问题。
问题在于post的路径助手用法为post_path(post)
,因为我使用的第一个参数必须是年份:as => :post
在routes.rb
中的参数化匹配中routes.rb
。
尽管如此,要使整个解决方案明确,还需要采取一些措施来使所有工作正常运行:
-
您必须为每个匹配添加正确的路径助手名称,例如
# 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_path
,posts_year_path("2012")
,posts_month_path("2012","12")
。我建议不要同时使用
:as => :post
在该匹配中:as => :post
,也不在模型文件中创建to_param
,因为它可以破坏你不期望的东西(对于我来说是active_admin
)。 -
控制器文件
posts-controller.rb
应填充需要提取的post,并在slug之前检查日期的正确性。 然而,在这种状态下它是可以的,什么都不打破。 -
模型文件
posts.rb
应以适当的格式填写年份和月份,例如:def year created_at.year end def month created_at.strftime("%m") end
我已经注意到,确实没有
to_param
方法。
这是你的完整routes.rb文件? 听起来你可能有一个先前的resources :posts
条目,基本上匹配/posts/:id
。 此外,我发布的路径文件中没有任何内容可以导致从根路径重定向到post,所以它必须是其他内容。