これが機能しない理由と、エラーのバックトレースに従う場合は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
なく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 []
次に、シンボルがルートで機能しない理由についての私の元のステートメントに戻ります。