Невозможно сопоставить REST-маршруты пользовательского метода с Ruby on Rails

Я новичок в Ruby-on-Rails, и мне трудно найти маршруты, соответствующие моему сервису API.

Я разработал свои собственные маршруты для ресурсов, следуя Google AIP-136.

Например, для следующих маршрутов

  • /books/{book_id}:doSomething
  • /books/{book_id}:doSomeOtherThing

В config/routes.rb я ожидал, что будет работать следующее:

post '/books/:id/\:doSomething', to: 'books#do_something_handler'
post '/books/:id/\:doSomeOtherThing', to: 'books#do_some_other_thing_handler'

Но это не работает. Я получаю ActionController::RoutingError (No route matches [POST] "/books/1234:doSomething"):

Я пробовал и другие вещи, но не получил очень удовлетворительного результата.

Может ли кто-нибудь помочь мне, как это сделать правильно.

С использованием -

  • Рельсы 7.1.3.4
  • рубин 3.3.4

Вам это действительно нужно? «Пользовательские методы следует использовать только для функций, которые невозможно легко выразить с помощью стандартных методов; по возможности отдавайте предпочтение стандартным методам из-за их последовательной семантики». Я бы, насколько это возможно, старался придерживаться стандартных маршрутов CRUD Rails. Также сомнительно, зачем вам применять набор рекомендаций для собственных API Google к своим собственным. Они, как обычно, чертовски странные.

max 29.07.2024 09:16

Привет @max, да, ты прав, конечно, лучше использовать стандартные методы, чем собственные. У меня просто очень конкретное требование. Кроме того, лично я считаю, что Google AIP предоставляет четко определенный набор рекомендаций по проектированию API. Однако, когда дело доходит до дизайна API, я не думаю, что есть какие-то последние слова. Самое главное, чтобы все стороны согласились на это.

Saurav Das 29.07.2024 21:24
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
1
2
53
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Использование ограничений:

# POST /books/1:doSomething
post "/books/:id::custom_method", 
  to: "books#do_something_handler",
  constraint: {custom_method: "doSomething"}

# POST /books/1:doSomethingElse
post "/books/:id::custom_method",
  to: "books#do_something_else",
  constraints: {custom_method: "doSomethingElse"}

Используя параметр action рельсов, в этом случае пользовательский метод должен соответствовать имени действия:

# POST /books/1:doSomething
# routes to `doSomething` controller action
post "/books/:id::action", controller: :books

Тестировать:

<%= form_with url: "books/1:doSomething" do |f| %>
  <%= f.submit %>
<% end %>

<%= form_with url: "books/1:doSomethingElse" do |f| %>
  <%= f.submit %>
<% end %>

маршрут с ограничениями:

Started POST "/books/1:doSomething" for 127.0.0.1 at 2024-07-26 15:36:50 -0400
Processing by BooksController#do_something as TURBO_STREAM
  Parameters: {"authenticity_token"=>"[FILTERED]", "commit"=>"Save ", "id"=>"1", "custom_method"=>"doSomething"}
Completed 200 OK in 3ms (ActiveRecord: 2.3ms | Allocations: 1332)


Started POST "/books/1:doSomethingElse" for 127.0.0.1 at 2024-07-26 15:36:52 -0400
Processing by BooksController#do_something_else as TURBO_STREAM
  Parameters: {"authenticity_token"=>"[FILTERED]", "commit"=>"Save ", "id"=>"1", "custom_method"=>"doSomethingElse"}
Completed 200 OK in 2ms (ActiveRecord: 0.1ms | Allocations: 892)

маршрут с параметром action:

Started POST "/books/1:doSomething" for 127.0.0.1 at 2024-07-26 15:11:22 -0400
Processing by BooksController#doSomething as TURBO_STREAM
  Parameters: {"authenticity_token"=>"[FILTERED]", "commit"=>"Save ", "id"=>"1"}
Completed 200 OK in 2ms (ActiveRecord: 0.1ms | Allocations: 1008)

Я все еще получаю ту же ошибку с этими изменениями

Saurav Das 26.07.2024 20:55

@SauravDas, я добавил свой тест. кажется, работает в обоих случаях.

Alex 26.07.2024 21:13

Привет @Alex, когда я добавляю оба маршрута для doSomething и doSomeOtherThing, они больше не передаются двум разным обработчикам.

Saurav Das 26.07.2024 21:32

Привет @Алекс, да, ты прав. Я по ошибке написал constraint без s, и рельсы вообще не жаловались, а просто продолжали неправильно маршрутизировать меня. Спасибо. Также увидел, что это тоже работает - '/books/:id::custom_method' без выхода из :. Принятие ответа.

Saurav Das 26.07.2024 22:06

Другие вопросы по теме