个人是比较偏向下面 (第 3 版) 的写法;但是疑惑的是这种写法的变化会带来什么好处么?还是仅仅只是提供多一种不同的写法而已
as 有额外的功能,设置别名,比如 users/index 是 users_path,你 as: 'xxx' ,你就可以用 xxx_path 了。不是写法的问题,这是个功能。
@catherine 是我问题没描述好! 其实想知道:
# Rails4.2
get 'help' => 'static_pages#help'
# Ralis5
get '/help', to: 'static_pages#help'
上面的写法过渡到下面的写法的这种变化有什么好处?还是仅仅只是提供多一种不同的写法而已?
#2 楼 @mukewells 其实我也有过这个疑问,后来慢慢看到 Rails 有很多这样的用法。
单对于这个,一般这么操作: 如果一个路由我只想指定一个 path,就直接
get 'path' => 'controller#action'
如果还想指定其他参数,如将 path 别名与路径分开(不想默认),就用这种
get 'path', to: 'controller#action', as: 'name'
总结:多参数使用 to,一个参数可以考虑=>
代替(更方便,少写点代码)
keyword arguments 从 ruby 2 开始就是被推荐的参数表风格. 好处来讲,keyword arguments 更方便的定义长可选参数表。另外在调用的时候也更具有可读性,这一点适合用来做 DSL.
PS: 能尽量避免写 rocket syntax 就尽量避免。既不好看也不简洁。1.9 的风格指导开始就尽量淘汰这种写法。2.2 以后更是支持
{'@a#complex%whatever.long___string__': true}
这种方式写 literal hash. 对于 string 和 symbol 区分不敏感的 kv 对都建议用新字面量定义方式。
看看get
的源码:
# https://github.com/rails/rails/blob/4-2-stable/actionpack/lib/action_dispatch/routing/mapper.rb#L650
def get(*args, &block)
map_method(:get, args, &block)
end
你说的两种写法传递的参数是不同的
get 'path', to: "controller#action"
# args = ["path", {:to => "controller#action"}]
get 'path' => 'controller#action'
# args = [{"path" => "controller#action"}]
往深一步看:
# https://github.com/rails/rails/blob/4-2-stable/actionpack/lib/action_dispatch/routing/mapper.rb#L687
def map_method(method, args, &block)
options = args.extract_options!
options[:via] = method
match(*args, options, &block)
self
end
# https://github.com/rails/rails/blob/4-2-stable/actionpack/lib/action_dispatch/routing/mapper.rb#L1470
# match 'path' => 'controller#action'
# match 'path', to: 'controller#action'
# match 'path', 'otherpath', on: :member, via: :get
def match(path, *rest)
......
end
match
方法太长就不贴了,extract_options!
是 rails 给 Array 扩展的方法,若数组对象最后一个元素是 hash 对象,就对这个数组调用pop
并返回pop
的返回值。实际上get
是在match
方法上做了一层封装。这样的话这两种写法传到match
方法的参数是这样的:
get 'path', to: "controller#action"
# path = "path"
# rest = [ { :to => "controller#action", :via => :get } ]
# 等于调用了 match "path", to: "controller#action", via: :get
get 'path' => 'controller#action'
# path = {"path" => "controller#action", :via => :get}
# rest = []
# 等于调用了 match "path" => "controller#action", via: :get
然后match
方法对这两张情况都做了处理,在这一段。实际上这两张写法都是一样的。不过正如 5 楼说的,ruby 从 1.9 后加入了{ key: 'value' }
这样的写法并推荐这样写,所以推荐上面那种写法