利用to_param实现Ruby on Rails 的URL优化
2011-03-09 22:15
447 查看
Active Model Conversions
Handles default conversions: to_model, to_key
and to_param.
to_param
()
Returns a string representing the object’s key suitable for use in URLs,
or nil if persisted? is false
在线资料:
http://my4java.itpub.net/post/9983/213158 http://www.thoughtrails.com/episodes/55-beautiful-routes-for-articles-on-rails3
同时使用一个永久性的
id
和一个完美的原文描述。为什么不使用
/accounts/edit/12-john-doe
来代替丑陋的
/accounts/edit/12
或脆弱的
/accounts/edit/john-doe
呢。你的代码有它需要查寻的用户
“
12
”,即使它以后更改它的名字为
“
john-d-doe
”
,而且你的用户及搜索爬虫都有
“
john-doe
”来使用。
实现上述想法很简单,因为
Rails
把
:id
看做是路由内的一个特殊的参数。它的特殊性是因为它试图在你创建
URL
时,在被传递的所有对象上调用
to_param
方法。这就说明了为什么
url_for :id => @account
等效于
url_for :id => @account.id
,因为活动记录模型有一个缺省的
to_param
方法,它返回对象的
id
。
你所要做的就是为你的模型定义自己的
to_param()
方法,并确保你没有明确地在你的
url_for
及
link_to
内包含
.id
,因为包含的话你将会跳过对你自己的
to_param
方法的调用。
class Account < ActiveRecord::Base
def to_param
"#{id}-#{full_name.gsub(/[^a-z1-9]+/i, '-')}"
end
end
当然了,这种解决办法的第二部分是,确保你的动作能够处理这
以post为例,
class Post < ActiveRecord::Base
validates :name, :presence => true
validates :title, :presence => true,
:length => { :minimum => 5 }
has_many :comments, :dependent => :destroy
has_many :tags
accepts_nested_attributes_for :tags, :allow_destroy => :true,
:reject_if => proc { |attrs| attrs.all? { |k, v| v.blank? } }
def to_param
"#{id}-#{name.gsub(/[^a-z0-9]+/i, '-')}"
end
end
一个问题:,新添加了一个post,得到url为:http://localhost/posts/8-lian-lian-blank-blank
对这个post的name update之后,相应的url变为:http://localhost/posts/8-lian-lian-blank-blank-underline-underline-good-end
但是这个时候,原来的url还能指向这个数据,并且内容也是最新的内容:http://localhost/posts/8-lian-lian-blank-blank
这样的话,一个相同的资源就有两个url可以进行访问,问题出在哪里呢?
还有,你可以看到,就算是虚构一个url,只要是前面的id(这里为8)一样,就能实现访问,: http://localhost/posts/8-lian-lian-blank-blank-xvgou-kkkkk
要解决这个问题,就必须分析,路由定义、生成、从url获取到资源及从资源反向生成URL的过程;路由的存取识别。
从此类型的url获取到资源的过程: http://www.cnblogs.com/orez88/articles/1520399.html(其实url在#{id}后的#{permalink}值可以任意修改,因为controller实际上还是根据前面的id来查询Product)。 Rails
只是将你的长
:id
字符串传递给数据库服务器,由于数据库看到的
id
列实际上是个整数,它会在使用之前试着把参数转换成一个数字,并且该转换会只使用任何它找到的数字化字符并去掉其余非数字化字符,即转换
“12-john-do”
为
12
。
相关文章推荐
- ruby on rails 4 中利用 remote:true 实现 ajax ,小记
- Ruby on rails 或 Ruby Goliath 利用redis + sidekiq 实现异步处理机制
- ruby connect to mssql from rails on windows
- Head First Rails: A learner's companion to Ruby on Rails
- Ruby on Rails,通过建立页面导航链接实现页面跳转
- 利用Radrails开发Ruby on Rails程序入门指南
- (转)How to Install Xcode, Homebrew, Git, RVM, Ruby & Rails on Snow Leopard, Lion, and Mountain Lion
- Ruby on Rails安装过程中出现"no such file to load -- mkmf"错误的解决方法。
- 受限环境下的Ruby On Rails程序优化
- ruby on rails 注册登录模块的简单实现
- Ruby on Rails 怎么实现整个网站的index
- Ruby on Rails,通过建立页面导航链接实现页面跳转
- “media change: please insert the disc labeled” when trying to install Ruby on Rails [duplicate]
- 通过js实现删除功能 ruby on rails
- How to Install Ruby on Rails on Ubuntu 12.04 LTS (Precise Pangolin) with RVM
- 利用Radrails开发Ruby on Rails程序入门指南
- Window7—64位:Ruby on Rails - “Add 'gem sqlite3'' to your Gemfile”
- ruby on rails 用prototype 实现表格排序
- ruby on rails 优化rails查询
- 通过js实现删除功能 ruby on rails