has_and_belongs_to_many
in my Rails project。スキーマは次のようになります
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のみを持つことができます。そして名前は本当に何でもかまいません。そして、彼らは常に少なくとも1匹の良い犬を飼っていなければなりません。
さて、私の質問に同意します。 APIクライアントの更新ユーザーAPIルートがあります。現在、犬を更新するために、ユーザーパラメータの一部として犬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を送信する必要があることに気づきました。犬の名前の1つを更新し、新しく作成した犬オブジェクトをユーザーの犬のリストに追加します。または、ユーザーに属する犬のリストから犬を削除します。
現時点では、私のAPIはDogオブジェクトの作成のみを許可しています。そして、これらの犬は多くの異なるユーザーを持つことができ、それらに属しているため、犬を直接更新または削除することは許可しません。これは、犬を共有する他のユーザーに影響を与え、犬はまったく変更されないためです。
ユーザーに関連付けられるすべてのdog_idを常に送信するようにAPIクライアントに要求し続ける必要があるかどうか疑問に思っています。 OR User APIコントローラで3つのアクションを作成する必要がある場合。1つは、ユーザーの犬のリストに犬を追加するものです。1つは、ユーザーの既存の犬を更新するものです(つまり、新しいdog_idをユーザーに関連付けます)そして、私の検証ごとに新しい犬の品種とdog_typeを共有する既存の犬IDを削除します)そして、ユーザーdogsのリストから犬を削除する1つのアクション。
Has_and_belongs_to_manyタイプの関係に対するこれらのタイプのAPIの典型は何ですか?
このタイプの関係の典型的なAPIが何かはわかりません。トピックの簡単なグーグルは決定的なものを明らかにしませんでした。
ただし、これは従来のCRUDの意味でのリソースの管理ではないことに注意してください。リソース間のassociationsを管理しています。
犬は従来の犬のエンドポイントを使用して管理されると思います。たとえば、新しい犬を作成するには:
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
これらのリクエストには、ユーザー関連の検証が適用されます。