Rails 3.2 友好的 url 日期路由 [英] Rails 3.2 friendly url routing by date
问题描述
我想实现具有以下能力的博客\新闻应用程序:
I want to implement blog\news application with ability to:
- 在根目录下显示所有帖子:
example.com/
- 显示某年回答的所有帖子:
example.com/2012/
- 显示回答某个年份和月份的所有帖子:
example.com/2012/07/
- 按日期和 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:
当我转到
localhost/
时,应用程序中断并说它已调用show
操作,但数据库中的第一个对象已被接收为 :year (原文如此!):
When I go to
localhost/
, the app breaks and says that it had invokedshow
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:
您必须为每个匹配项添加正确的路径助手名称,例如
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_path
、posts_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屋!