拥有并属于许多 API 个更新

Has and belongs to many API updates

我的 Rails 项目中有一个 has_and_belongs_to_many。架构如下所示

    create_table :dogs do |t|
      t.string :name
      t.string :breed
      t.string :dog_type
    end

    create_table :users_dogs, id: false do |t|
      t.belongs_to :user
      t.belongs_to :dog
      t.index ["user_id", "dog_id"], name: "by_user_and_dog", unique: true
      t.index ["user_id"], name: "index_users_dogs_on_user_id"
      t.index ["dog_id"], name: "index_users_dogs_on_dog_id"
    end

    create_table :users do |t|
      t.string :name
      t.string :email
    end

还有我的模特

class User < ApplicationRecord
  has_and_belongs_to_many :dogs

  validate :only_one_good_dog_per_breed
  validate :only_one_bad_dog_per_breed
  validate :at_least_one_good_dog
end

class Dogs < ApplicationRecord
  DOG_TYPES = %w[good bad].freeze
  BREEDS = %w[poodle bulldog]
  has_and_belongs_to_many :users

  validates :name, :breed, :dog_type, presence: true
  validates :breed,
            inclusion: { in: BREEDS, allowed_options: BREEDS.join(", ") }
  validates :dog_type,
            inclusion: { in: DOG_TYPES, allowed_options: DOG_TYPES.join(", ") }
  validates :name, uniqueness: { scope: [:breed, :dog_type] }
end

如您所见,用户可以养的狗有一些限制。他们每个品种只能有 1 dog_type。这个名字真的可以是任何东西。而且他们必须始终至少拥有一只好狗。

好的,现在回答我的问题。我的 API 客户有一个更新用户 API 路由。目前他们可以发送他们的 Dog id 作为用户参数的一部分来更新他们的狗。

    def update
      if @user.update(user_params)
       render json: @user, status: :ok
      else
       render json: { errors: @user.errors }, status: :unprocessable_entity
      end
    end

    private

    def user_params
      params.require(:user).permit(
        :name,
        dog_ids: []
      )
   end

现在我意识到,如果我的 API 客户想要执行以下任何操作,他们将必须始终发送所有用户狗 ID,更新其中一只狗的名字,添加新创建的 Dog 对象添加到用户拥有的狗的列表中,或者从属于用户的狗列表中删除狗。

截至目前,我的 API 只允许创建 Dog 对象。由于这些狗可以拥有并属于许多不同的用户,我不想直接更新或删除狗,因为这可能会影响我的其他共享狗的用户,而他们的狗根本没有改变。

我想知道我是否应该继续要求我的 API 客户端始终发送将与我的用户关联的所有 dog_ids。或者,如果我应该在我的用户 API 控制器中创建三个动作。一个是将一只狗添加到用户的狗列表中。一个是更新用户现有的狗(即,将新的 dog_id 关联到用户并删除共享新狗品种的现有狗 ID,并根据我的验证 dog_type)。以及从用户狗列表中删除狗的一个操作。

对于 has_and_belongs_to_many 类型的关系,这些 API 类型的典型特征是什么?

我不确定 API 这种关系的典型特征是什么。快速 Google 没有找到任何确定的主题。

但是,需要注意的一件事是,这不是经典 CRUD 意义上的资源管理。它正在管理资源之间的关联

我想狗会使用传统的狗端点进行管理。例如创建一只新狗:

POST/api/v1/dogs
PARAMS: 
- name
- breed
- dog_type

然后要创建或删除关联,API 客户端将向这些端点发出请求:

POST /api/v1/users/:user_id/dogs/:id

DELETE /api/v1/users/:user_id/dogs/:id

将对这些请求强制执行与用户相关的验证。