我想实现博客\新闻应用程序,并且能够:
- 显示根目录下的所有帖子:
example.com/
- 显示回答某年的所有帖子:
example.com/2012/
- 显示回答某个年份和月份的所有帖子:
example.com/2012/07/
- 按日期和标题显示一些帖子:
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
操作中使用参数,并在 show
操作中通过 slug 进行发布(可以选择检查日期是否正确):
# 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 中彻夜搜索所学到的全部内容。
但问题是对于我这个 Rails 新手来说奇怪的事情不断发生:
当我转到
localhost/
时,应用程序中断并表示它已调用show
操作,但数据库中的第一个对象已被接收为 :year (原文如此!):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
时,会发生同样的事情: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">}
我觉得有一些很简单的东西我没有做过,但我找不到它是什么。
无论如何,当这个问题得到解决时,这篇文章将会很有帮助,因为只有针对没有日期的 url 中的 slugs 以及类似但没有用的问题的解决方案。
最佳答案
问题出在 post 的路径帮助程序使用 post_path(post)
中,因为第一个参数必须是年份,因为我在 中使用 :as => :post
routes.rb
中的参数化匹配。
尽管如此,为了使整个解决方案变得清晰,需要采取一些措施才能使所有工作正常进行:
您必须为每个匹配添加正确的路径助手名称,例如
# Get /posts/2012/07/slug-of-the-post match "/posts/:year/:month/:slug", <...>, :as => :post_date
现在您可以在 View 中使用
post_date_path("2012","12","end-of-the-world-is-near")
。如果命名正确,
posts_path
、posts_year_path("2012")
、posts_month_path("2012","12")
也是如此。我建议不要在匹配中使用
:as => :post
也不在模型文件中创建to_param
因为它可能会破坏你不期望的东西(如active_admin
对我来说)。Controller 文件
posts-controller.rb
应填充需要在 slug 之前提取和检查日期正确性的帖子。尽管如此,在这种状态下它还是可以的,不会破坏任何东西。模型文件
posts.rb
应以正确的格式填写年份和月份提取物,例如:def year created_at.year end def month created_at.strftime("%m") end
正如我已经注意到的,没有真正需要的
to_param
方法。
关于ruby-on-rails - Rails 3.2 按日期友好的 url 路由,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11569876/