这不起作用以及如果您遵循错误回溯的原因是因为mapper.rb
Rails 中的以下行。
def match(path, *rest)
if rest.empty? && Hash === path
options = path
path, to = options.find { |name, value| name.is_a?(String) }
options[:to] = to
options.delete(path)
paths = [path]
else
options = rest.pop || {}
paths = [path] + rest
end
options[:anchor] = true unless options.key?(:anchor)
if options[:on] && !VALID_ON_OPTIONS.include?(options[:on])
raise ArgumentError, "Unknown scope #{on.inspect} given to :on"
end
paths.each { |_path| decomposed_match(_path, options.dup) }
self
end
这由幕后的所有方法调用(例如delete
, post
, get
, put
)。我们特别寻找的那一行是这样的:
path, to = options.find { |name, value| name.is_a?(String) }
不知道他们为什么要检查 String 但因为名称是符号而不是 aString
而是 a Symbol
。这几乎将该路径作为 nil 值发送,decomposed_match
从而导致您无法在路线中使用符号的原因。
笔记
resources :products do
member do
get :delete #this works
delete delete: "products#destroy" #this doesn't work
delete "delete" => "products#destroy" #but this works
end
end
之所以起作用,是因为调用方法get :delete
之前的那一行。match
具体下这个方法
def map_method(method, *args, &block)
options = args.extract_options!
options[:via] = method
args.push(options)
match(*args, &block)
self
end
该行args.extract_options!
从数组中删除了一个散列。您可以在文件下找到它,extract_options.rb
它是类的添加方法Array
。
无论如何,因为get :delete
不是散列而是单个参数,所以它被映射到这样的东西
Path: [delete]
Options [{via: "get"}]
现在,其他的像这样被映射,例如delete delete: "product#destroy"
Path {:delete=>"collaborators#destroy", via: "delete"}
Options []
然后回到我最初关于为什么符号在路线中不起作用的陈述。