Rails: маршруты GET и POST для одного и того же пути вызывают ошибку ArgumentError

#ruby-on-rails #ruby-on-rails-5

#ruby-on-rails #ruby-on-rails-5

Вопрос:

Когда я посещаю /contact , я получаю:

 ArgumentError (wrong number of arguments (given 1, expected 0)):
app/controllers/contact_controller.rb:6:in `send'
  

Вот содержимое config/routes.rb :

 Rails.application.routes.draw do
  root to: 'home#index'  
  get  'contact', to: 'contact#index'
  post 'contact', to: 'contact#send'
end
  

Приводит ли включение маршрута для обоих get и post для одного и того же пути к тому, что get он не будет использоваться? ContactController имеет пустые действия для index и send , но index , похоже, игнорируется.

Ответ №1:

Я думаю, проблема в том, что Rails использует Object#send для вызова методов контроллера по имени, но у вас есть свой собственный send метод. Глубоко внутри системы маршрутизации Rails она знает, что она должна направлять GET /contact к методу, имя которого является строкой 'index' ; код для этого будет выглядеть примерно так:

 controller_instance = an_instance_of_ContactController_from_somewhere
controller_method   = 'index' # This string will be extracted from the `get 'contact', to: '...'` call in routes.rb

controller_instance.send(controller_method)
  

Вы должны иметь возможность переименовать свой send метод во что-то другое, обновить свой routes.rb , и все должно быть в порядке; например:

 post 'contact', to: 'contact#send_message'
  

и затем в contact_controller.rb :

 def send_message
  #...
end
  

Комментарии:

1. Очень проницательное наблюдение. Для определения этого потребовалось бы довольно много времени, поскольку это проблема внутренней реализации, которая, TBH, вероятно, не должна возникать, особенно учитывая тот факт, что __send__ также доступна.

2. @engineersmnky Спасибо, но это не большой переход от «строки к вызову метода» (фундаментальная часть маршрутизации Rails) и «есть метод с именем send » к проблеме переопределения. Похоже, что #send используется намного чаще, чем #__send__ в Rails, __send__ по-видимому, в более новом коде.