给出代码(在routes.rb中):
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
为什么行delete delete: "products#destroy"
不起作用且行delete "delete" => "products#destroy"
有效?
Rails版本3.2.11
答案 0 :(得分:3)
如果要将删除操作映射到销毁,则应使用match
match 'products/:id/delete', controller: :products, action: :destroy, via: :delete
但我没有理由这样做。在我看来,你应该坚持使用rails default destroy action。
并且它不起作用,因为在资源中你已经指定了控制器并且它用于使用适当的http协议添加动作
答案 1 :(得分:1)
这不起作用以及如果您遵循错误回溯的原因是由于Rails中mapper.rb
中的以下行。
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
而是Symbol
。这几乎将该路径作为零值发送到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 []
然后它回到我原来的陈述,说明为什么符号在路线中不起作用。
答案 2 :(得分:0)
只有Ruby 1.9版支持新的哈希语法。您使用的是哪个版本的Ruby?