Rails 中漂亮(过时)的 RESTful URL [英] Pretty (dated) RESTful URLs in Rails

查看:47
本文介绍了Rails 中漂亮(过时)的 RESTful URL的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我希望我的网站的网址如下所示:

example.com/2010/02/my-first-post

我有我的 Post 模型,带有 slug 字段('my-first-post')和 published_on 字段(我们将从中扣除网址中的年和月部分).

我希望我的 Post 模型是 RESTful 的,所以像 url_for(@post) 这样的东西就像它们应该的那样工作,即:它应该生成上述 url.

有没有办法做到这一点?我知道您需要覆盖 to_param 并设置 map.resources :posts:requirements 选项,但我无法让它全部工作.

<小时>

我已经快完成了,我已经完成了 90%.使用 resource_hacks 插件 我可以做到这一点:

map.resources :posts, :member_path =>'/:年/:月/:slug',:member_path_requirements =>{:年 =>/[\d]{4}/, :month =>/[\d]{2}/, :slug =>/[a-z0-9\-]+/}耙路线(……)post GET/:year/:month/:slug(.:format) {:controller=>"posts", :action=>"show"}

并在视图中:

<%= link_to 'post', post_path(:slug => @post.slug, :year => '2010', :month => '02') %>

生成正确的 example.com/2010/02/my-first-post 链接.

我也希望这样:

<%= link_to 'post', post_path(@post) %>

但它需要覆盖模型中的 to_param 方法.应该相当简单,除了to_param 必须返回String,而不是我想要的Hash.

class Post '我的第一篇文章', :year =>'2010', :month =>'02'}结尾结尾

导致can't convert Hash into String错误.

这似乎被忽略了:

def to_param'2010/02/我的第一篇文章'结尾

因为它导致错误:post_url failed to generate from {:action=>"show", :year=>#<Post id: 1, title: (...)(它错误地将@post 对象分配给了 :year 键).我对如何破解它一无所知.

解决方案

这仍然是一个 hack,但以下有效:

application_controller.rb 中:

def url_for(options = {})if options[:year].class.to_s == 'Post'帖子=选项[:年份]选项[:year] = post.year选项[:月] = post.month选项[:slug] = post.slug结尾超级(选项)结尾

以下将起作用(在 Rails 2.3.x 和 3.0.0 中):

url_for(@post)post_path(@post)link_to @post.title, @post等等.

这是一些不错的灵魂对我的类似问题的回答,自定义 RESTful 资源的 url_for(复合键;不仅仅是 id).

I'd like my website to have URLs looking like this:

example.com/2010/02/my-first-post

I have my Post model with slug field ('my-first-post') and published_on field (from which we will deduct the year and month parts in the url).

I want my Post model to be RESTful, so things like url_for(@post) work like they should, ie: it should generate the aforementioned url.

Is there a way to do this? I know you need to override to_param and have map.resources :posts with :requirements option set, but I cannot get it all to work.


I have it almost done, I'm 90% there. Using resource_hacks plugin I can achieve this:

map.resources :posts, :member_path => '/:year/:month/:slug',
  :member_path_requirements => {:year => /[\d]{4}/, :month => /[\d]{2}/, :slug => /[a-z0-9\-]+/}

rake routes
(...)
post GET    /:year/:month/:slug(.:format)      {:controller=>"posts", :action=>"show"}

and in the view:

<%= link_to 'post', post_path(:slug => @post.slug, :year => '2010', :month => '02') %>

generates proper example.com/2010/02/my-first-post link.

I would like this to work too:

<%= link_to 'post', post_path(@post) %>

But it needs overriding the to_param method in the model. Should be fairly easy, except for the fact, that to_param must return String, not Hash as I'd like it.

class Post < ActiveRecord::Base
  def to_param
   {:slug => 'my-first-post', :year => '2010', :month => '02'}
  end
end

Results in can't convert Hash into String error.

This seems to be ignored:

def to_param
  '2010/02/my-first-post'
end

as it results in error: post_url failed to generate from {:action=>"show", :year=>#<Post id: 1, title: (...) (it wrongly assigns @post object to the :year key). I'm kind of clueless at how to hack it.

解决方案

It's still a hack, but the following works:

In application_controller.rb:

def url_for(options = {})
  if options[:year].class.to_s == 'Post'
    post = options[:year]
    options[:year] = post.year
    options[:month] = post.month
    options[:slug] = post.slug
  end
  super(options)
end

And the following will work (both in Rails 2.3.x and 3.0.0):

url_for(@post)
post_path(@post)
link_to @post.title, @post
etc.

This is the answer from some nice soul for a similar question of mine, url_for of a custom RESTful resource (composite key; not just id).

这篇关于Rails 中漂亮(过时)的 RESTful URL的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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