Rails3 Route常用用法

我们都知道在Rails中的config/route.rb文件定义了路由的设定,这次充分学习了Rails3中Route的常用用法,整理并分享在这里。

默认路由:

match '/:controller(/:action(/:id))'

自定义路由:

match 'products/:id', :to => 'catalog#view'

命名路由:

match 'logout', :to => 'sessions#destroy', :as => 'logout'

根路由:

root :to => 'welcome#show'

路由简写技巧:

:to 键的省略

match 'account' => 'account#index'

# 相当于:

match 'account', :to => 'account#index'
  
match 'info' => 'projects#info', :as => 'info'

注意: :as 在rails3中是改变 helper, 在rails2中是改变 path

当路径和控制器(及action)一至时,可省略指派控制器部分

match 'account/overview'
# 相当于:  
match 'account/overview', :to => 'account#overview'

Verb路由

当需要限制http请求方法的时候通过键 :via ,也可以直接把方法写在最前面:

get 'account/overview'
# 相当于:  
match 'account/overview', :via => 'get'
  
match 'account/setup', :via => [:get, :post]
# 支持get\post\put\delete四种HTTP方法

scope路由

:path 改变Path,:module 改变Controller, :name_prefix || :as 改变 helper

scope 'admin' do
  resources :posts
end
# 行当于:
scope :path => 'admin' do
  resources :posts
end

生成路由:

posts  GET  /admin/posts(.:format)  {:controller=>"posts", :action=>"index"}

posts  POST  /admin/posts(.:format)  {:controller=>"posts", :action=>"create"}

new_post  GET  /admin/posts/new(.:format)  {:controller=>"posts", :action=>"new"}

edit_post  GET  /admin/posts/:id/edit(.:format)  {:controller=>"posts", :action=>"edit"}

post  GET  /admin/posts/:id(.:format)  {:controller=>"posts", :action=>"show"}

post  PUT  /admin/posts/:id(.:format)  {:controller=>"posts", :action=>"update"}

post  DELETE  /admin/posts/:id(.:format)  {:controller=>"posts", :action=>"destroy"}

scope :module => 'admin' do
  resources :posts
end
# 相当于:
resources :posts, :module => 'admin'

生成路由:

posts  GET  /posts(.:format)  {:controller=>"admin/posts", :action=>"index"}

posts  POST  /posts(.:format)  {:controller=>"admin/posts", :action=>"create"}

new_post  GET  /posts/new(.:format)  {:controller=>"admin/posts", :action=>"new"}

edit_post  GET  /posts/:id/edit(.:format)  {:controller=>"admin/posts", :action=>"edit"}

post  GET  /posts/:id(.:format)  {:controller=>"admin/posts", :action=>"show"}

post  PUT  /posts/:id(.:format)  {:controller=>"admin/posts", :action=>"update"}

post  DELETE  /posts/:id(.:format)  {:controller=>"admin/posts", :action=>"destroy"}

scope :name_prefix => 'admin' do
  resources :posts
end
# 相当于:
resources :posts, :name_prefix => 'admin'

生成路由:

admin_posts  GET  /posts(.:format)  {:controller=>"posts", :action=>"index"}

admin_posts  POST  /posts(.:format)  {:controller=>"posts", :action=>"create"}

new_admin_post  GET  /posts/new(.:format)  {:controller=>"posts", :action=>"new"}

edit_admin_post  GET  /posts/:id/edit(.:format)  {:controller=>"posts", :action=>"edit"}

admin_post  GET  /posts/:id(.:format)  {:controller=>"posts", :action=>"show"}

admin_post  PUT  /posts/:id(.:format)  {:controller=>"posts", :action=>"update"}

admin_post  DELETE  /posts/:id(.:format)  {:controller=>"posts", :action=>"destroy"}

scope 'admin', :module => 'admin', :name_prefix => 'admin' do
  resources :posts
end
# 相当于:
namespace 'admin' do
  resources :posts
end

生成路由:

admin_posts  GET  /admin/posts(.:format)  {:controller=>"admin/posts", :action=>"index"}

admin_posts  POST  /admin/posts(.:format)  {:controller=>"admin/posts", :action=>"create"}

new_admin_post  GET  /admin/posts/new(.:format)  {:controller=>"admin/posts", :action=>"new"}

edit_admin_post  GET  /admin/posts/:id/edit(.:format)  {:controller=>"admin/posts", :action=>"edit"}

admin_post  GET  /admin/posts/:id(.:format)  {:controller=>"admin/posts", :action=>"show"}

admin_post  PUT  /admin/posts/:id(.:format)  {:controller=>"admin/posts", :action=>"update"}

admin_post  DELETE  /admin/posts/:id(.:format)  {:controller=>"admin/posts", :action=>"destroy"}

在路由中定义跳转:

match "/posts/github" => redirect("http://github.com/rails.atom")

# 地址 /foo/1 会自动跳转到 /bar/1s
match "/foo/:id", :to => redirect("/bar/%{id}s")
  
# /account/proc/inosin 会自动跳转到 /inosins
match 'account/proc/:name', :to => redirect {|params|
"/#{params[:name].pluralize}" }
  
match "/stories" => redirect {|p, req| "/posts/#{req.subdomain}" }

路由中的限制:

# 限制 id 只能为数字  
match "/posts/show/:id", :to => "posts#index", :id => /\d+/  
match "/posts/show/:id", :to => "posts#index", :constraints => {:id => /\d+/}  
  
# 限制子域名  
match "photos", :constraints => {:subdomain => "admin"}   
  
# 限制访问者 IP  
constraints(:ip => /127.0.0.1/) do  
  match  '/questions', :to => redirect("http://www.stackoverflow.com/")  
end  
  
# 当访问者 ip 是 192.168.1.* 的来访者访问 子域名为 "test"  
match "/ttt" => proc{|env| [200, {}, ["hello test"]]}, \  
    :constraints => {:subdomain => "test", :ip => /192\.168\.1\.\d+/}

路由通配符:

resources :photos, :id => /\d+/  
match 'photos/*other' => 'photos#unknown'  
#上面这两行路由则会把不符合7种path的其他url全部解析到PhotoController#unknown中去处理,params[:other]可得到path中/photos/之后的部分,注意这两行的顺序不能颠倒  
  
match 'books/*section/:title' => 'books#show'   
# 例如:books/some/section/last-words-a-memoir 中 params[:section] = "some/section", params[:title] = "last-words-a-memoir".  
  
match '*a/foo/*b' => 'test#index'   
# 例如:zoo/woo/foo/bar/baz 中 params[:a] = "zoo/woo", params[:b] = "bar/baz"

HTTP协议之状态码

一篇不错的讲解HTTP状态码的Blog,收藏了!

Http协议之状态码详解


7-patterns-to-refactor-active-record

Vincent推荐的一篇非常不错的文章,看后非常受益。

7 Patterns to Refactor Fat ActiveRecord Models


Sublime Text 2 Plugin

之前做android开发一直用eclipse做编辑器,之后接触ruby之后便开始用Sublime Text 2,渐渐的才发现此等编辑器的好处,也越来越依赖它。

Sublime Text 2是一个轻量、简洁、高效、跨平台的编辑器,方便的配色以及兼容vim快捷键等各种优点博得了很多前端开发人员的喜爱。之前也不并知道它有这么多插件的扩展与支持,直到vincent问到有没有在用cTags插件,才知道原来Sublime通过插件也可以实现一些大型IDE的功能,遂google一下,本篇Blog就来介绍下Sublime下经常使用的插件。

安装包控制(Package Control)

打开Sublime Text 2,点击 Tools -> Command Palette 调出控制台Console;

将以下代码粘贴进命令行中并回车:

import urllib2,os;pf='Package Control.sublime-package';ipp=sublime.installed_packages_path();os.makedirs(ipp) if not os.path.exists(ipp) else None;open(os.path.join(ipp,pf),'wb').write(urllib2.urlopen('http://sublime.wbond.net/'+pf.replace(' ','%20')).read())

重启 Sublime Text 2,如果在 Preferences -> Package Settings中见到Package Control这一项,就说明安装成功了。

安装Alignment插件

对于某些喜欢整齐的程序员来说,看到下面这种情况可能是让其无法忍受的:

var joe = 'joe';
var johnny = 'johnny';
var quaid = 'quaid';

一定要改成这样才会安心:

var joe    = 'joe';
var johnny = 'johnny';
var quaid  = 'quaid';

Sublime Text 2 之中,一个 Sublime Alignment 插件也可以轻松实现。

1.按下 Ctrl + Shift + P 调出命令面板。

2.输入 install 调出 Package Control: Install Package 选项,按下回车。

3.在列表中找到 Alignment,按下回车进行安装。

4.重启 Sublime Text 2 使之生效。现在通过选中文本并按 Ctrl + Shift + A 就可以进行对齐操作了。

Vim模式

是的,Sublime Text 2已经支持 Vim 的编辑模式了,如果更喜欢 Vim 的编辑模式,可以通过以下方法来激活 Vintage mode:

1.按下 Ctrl + Shift + P 调出命令面板。

2.输入 settings user 调出 Preferences:Settings - User,并按下回车。

3.这时会打开一个 Preferences.sublime-settings 的文件, 如果是第一次修改,它应该是个空文件,把以下文本粘贴进去:

{
  "ignored_packages": []
}

4.保存这个文件,这时按下 ESC 键,再按下一些你熟悉的 Vim 命令,是不是很有亲切感?

安装 Soda 主题

这里所讲的主题不同于针对代码的 Color Scheme,是指针对 Sublime 程序本身的主题,目前可以安装的是 Ian Hill 的 Soda。

因为源中已经添加,所以这款主题的安装同样可以通过 Package Control,非常方便。目前 Soda 主题提供了明暗两种风格。

激活方法,同样要修改 Preferences:Settings - User:

1.按下 Ctrl + Shift + P 调出命令面板。

2.输入 user settings 调出 Preferences:Settings - User,并按下回车。

3.添加以下代码激活 Soda Light 主题:

{
  "theme": "Soda Light.sublime-theme"
}

添加以下代码激活 Soda Dark 主题:

{
  "theme": "Soda Dark.sublime-theme"
}

4.保存生效。

安装cTags插件

这个插件能跨文件跳转,实现像eclipse可那样以追踪函数的功能,从此更喜欢上Sublime了。安装方法:

1.按下 Ctrl + Shift + P 调出命令面板。

2.输入 install 调出 Package Control: Install Package 选项,按下回车。

3.在列表中找到 ctags,按下回车进行安装。

4.ubuntu下安装运行命令:sudo apt-get install exuberant-ctags。

5.在sublime项目文件夹右键, 会出现Ctag:Rebuild Tags 的菜单。点击它,然后会生成.tags的文件。

然后在你代码中, 光标放在某个函数上, 点击ctrl+shift+鼠标左键 就可以跳转到函数声明的地方。

Zen Coding

如果经常要写一些前端的代码,这个插件也是必不可少的,还不知道ZenCoding的同学推荐去看一下:《Zen Coding: 一种快速编写HTML/CSS代码的方法》

Git

一个整合GIT和Sublime Text的插件,执行了很多你需要使用的命令。


Ruby: eval && binding

Ruby语言中有许多方法,灵活的运用这些方法,可以帮助我们轻松的掌握Ruby的编程技巧。最近遇到eval与binding,对于我这个ruby新手来说很陌生,于是就学习了下,并在这里记录并分享下来。

eval

其实eval方法很简单,就是把字符串当作ruby程序来执行并返回结果,例子说话:

a = 1
str = "if a == 1 then puts true else puts false end"
eval(str)     #=> true

binding

生成并返回Binding对象。该对象包含变量、方法等的环境信息,它通常用作Eval的第二参数。来看官方提供示例:

Example1

class Demo
  def initialize(n)
    @secret = n
  end

  def get_binding
    return binding
  end
end

k1 = Demo.new(99)
b1 = k1.get_binding
k2 = Demo.new(-3)
b2 = k2.get_binding

eval("@secret", b1)   #=> 99
eval("@secret", b2)   #=> -3
eval("@secret")       #=> nil

Example2

def get_binding(param)
  binding
end
b = get_binding("hello")
b.eval("param")   #=> "hello"

至此,eval和binding应该理解什么意思了,又一次体现了ruby语法的灵活性。