如何处理来自网站的API调用,从而显示属于该网站的信息?

How to deal with API call from website and consequently show information belonging to the website?

在我的 Ruby on Rails 应用程序中,自行车租赁公司可以管理他们所有的自行车(预订、付款等)。

目标

我想为自行车租赁公司提供在他们自己的网站上实施预订表格的选项,这样他们就可以让客户为特定的自行车创建预订。

然后,此预订表格会将可用的自行车从我的 Rails 应用程序带到他们的网站,然后将新的预订数据发送回 Rails 应用程序。

问题

我如何 link 商店的网站,到我的应用程序中的特定 Shop。因此,确保特定网站确实应该能够获取属于 Shop 的信息。

代码

型号

class Shop < ApplicationRecord
  has_many :bike_categories, dependent: :destroy
  has_many :bikes, through: :bike_categories
  has_many :user_shops, dependent: :destroy
  has_many :users, through: :user_shops
  has_many :reservations, dependent: :destroy
  accepts_nested_attributes_for :users, allow_destroy: true, reject_if: ->(attrs) { attrs['email'].blank? || attrs['role'].blank?}
end

class User < ApplicationRecord
  has_many :user_shops, dependent: :destroy
  has_many :shops, through: :user_shops
  accepts_nested_attributes_for :user_shops
  enum role: [:owner, :admin, :employee, :accountant, :demo, :app_owner]
end

class Reservation < ApplicationRecord
  belongs_to :shop
  belongs_to :bike
end

controllers/api/v1/reservations_controller

  def create
    # How to know/specify which shop?
    @shop = Shop.new(shop_params)
    authorize @shop
    if @shop.save
      render :show, status: :created
    else
      render_error
    end
  end

这是你的教科书范例nested resource。在 REST 中,嵌套资源嵌套在另一个资源的路径中:

/authors/1/books
/countries/uk/cities
/blogs/1/posts/2

这里的妙处在于路径本身描述了资源之间的关系。

您可以通过将块传递给 resources:

来使路由嵌套
namespace :api do
  namespace :v1 do
    resources :shops do 
      resources :reservations, shallow: true
    end
  end
end

shallow 选项只使收集路由嵌套(新建、创建、索引),这通常是一件好事,因为记录无论如何都有一个唯一的 ID,可以通过它来获取它们。

/blogs/1/posts/2 是深度嵌套路由的一个例子。如果 id 是唯一的,我们应该能够通过 /posts/2 获得完全相同的资源,这大大简化了代码,因为它不需要知道 blog.

module API
  module V1
    class ReservationsController < ApiController
      before_action :set_shop, only: [:create, :index]

      # GET /api/v1/shops/1/resevations
      def index
        @reservations = @shop.reservations
      end 

      # POST/api/v1/shops/1/resevations
      def create
        @reservation = @shop.reservations.new(reservation_params)
        # ...
      end

      # ...
      private

      def set_shop
         @shop = Shop.includes(:reservations).find(params[:shop_id])
      end

      # ...
    end
  end
end