Как передать параметры запроса в контроллер Rails API? - PullRequest
0 голосов
/ 29 января 2020

В моем приложении Ruby on Rails компании по прокату велосипедов могут управлять всеми своими велосипедами (бронирование, оплата и т. Д. c.).

Контекст Я хотел бы предложить компаниям по прокату велосипедов (shops) возможность создать форму бронирования на своем собственном веб-сайте, чтобы они могли позволить клиентам бронировать bike.

  • В этой форме бронирования будет указано bike_categories, из которых bikes доступны на определенную дату arrival и departure.

Вопрос Чтобы справиться с этим, я хотел бы сгенерировать действие контроллера API, показывающее availability для определенного bike_category с отображением count для числа из доступных bikes принадлежащих этому bike_category.

Согласно этому сообщению

Разработка API запросов RESTful с длинным списком параметров запросов

Я должен иметь возможность обрабатывать запросы в моем API , но как мне получить запросы в моем контроллере Rails?

код

модели

class Shop < ApplicationRecord
  has_many :bike_categories, dependent: :destroy
  has_many :bikes, through: :bike_categories
  has_many :reservations, dependent: :destroy
end

class Reservation < ApplicationRecord
  belongs_to :shop
  belongs_to :bike
end

class Bike < ApplicationRecord
  belongs_to :bike_category
  has_many :reservations, dependent: :destroy
end

class BikeCategory < ApplicationRecord
  belongs_to :shop
  has_many :bikes, dependent: :destroy
end

маршруты

# api
  namespace :api, defaults: { format: :json } do
    namespace :v1 do
      resources :shops, only: [ :show ]
      resources :reservations, only: [ :show, :create ]
      resources :bike_categories, only: [:index, :show, :availability]
    end
  end

controller / api / v1 / bike_categories_controller.rb


class Api::V1::BikeCategoriesController < Api::V1::BaseController
  acts_as_token_authentication_handler_for User, only: [:show, :index, availability]

  def availability
    # How to get the bike_category, arrival and departure?
  end

end

Ответы [ 2 ]

2 голосов
/ 29 января 2020

Rails предоставляет параметры строки запроса в params га sh, который на самом деле представляет собой коллаж:

  • Тело запроса (для методов POST, PATCH, PUT и c., Которые иметь тело)
  • Строка запроса
  • Именованные сегменты из пути (например, params[:id]).

Так что в этом нет ничего особенного:

class Api::V1::BikeCategoriesController < Api::V1::BaseController
  acts_as_token_authentication_handler_for User, only: [:show, :index, availability]
  def availability
    # How to get the bike_category, arrival and departure?
    bike_category = params[:bike_categories] 
    arrival = params[:arrival]
    departure = params[:departure]
  end
end

Однако ваши маршруты настроены неправильно. На самом деле у вас нет маршрута для availiblity. Опция only и except просто ограничивает вывод маршрутов CRUD по умолчанию, которые генерирует resources. Допустимые значения:

  • show
  • index
  • new
  • create
  • edit
  • update
  • delete

Любые другие значения не влияют вообще. Если вы хотите добавить дополнительный маршрут RESTful, вы можете сделать это так:

resources :bike_categories, only: [:index, :show] do
  # GET .../bike_categories/:bike_category_id/availability 
  get :availability 

  # GET .../bike_categories/:id/availability 
  get :availability, on: :member

  # GET .../bike_categories/availability 
  get :availability, on: :collection
end
1 голос
/ 29 января 2020

Вы можете использовать has_scope gem .

Внутри вашей модели Bike вы можете создать область действия not_reserved (я предполагаю, что вы назвали свои столбцы прибытия и отправления arrive_at и departure_at:

class Bike < ApplicationRecord
# ...
  scope :not_reserved, -> arrive, departure { left_outer_joins(:reservations).distinct.where("reservations.arrival_at < ? AND reservations.departure_at > ?", departure, arrive) }
  # If you need to return the result for a specific bike category
  scope :by_bike_category, -> bike_category_id { where(bike_category_id: bike_category_id) }
# ...
end

В вашем BikeCategoriesController:

class Api::V1::BikeCategoriesController < Api::V1::BaseController
  has_scope :not_reserved, using: [:arrive, :departure], type: :hash
  has_scope :by_bike_category

  def availability
    category_availability = apply_scopes(Bike).group(:bike_category_id).count

    render json: category_availability
  end

end

И ваша строка запроса будет выглядеть так:

?not_reserved[arrive]=20200110&not_reserved[departure]=20200125&by_bike_category=3
...