- ユーザーとして、お気に入りの本をブック リストに追加できます。
- 別のユーザーが同じ本をブック リストに追加します。
データベースには書籍のインスタンスが 1 つしかないはずですが、ユーザーと書籍の関連付けは 2 つ必要です。
class User has_many :bookReferences has_many :books, through: :bookReferences class Book validates_uniqueness_of :title has_many :bookReferences has_many :users, through: :bookReferences class BookReference belongs_to :user belongs_to :book
最初の問題は、書籍が既にシステムに存在する場合、書籍が一意ではないため、2 番目のユーザーの bookReference が作成されないことです。
そのため、書籍が既にシステムに存在する場合は、bookReference テーブルに関連付けレコードを作成するだけです。
2 番目の問題は、ユーザーが本を削除したときに、その本を参照している唯一のユーザーでない限り、本への参照のみを削除することです。
基本的に、これは私が達成しようとしている使用法の完全な概要です。
user1.books.first
=> id: 1, title: "Moby Dick"
user2.books.first
=> id: 1, title: "Moby Dick"
books.all
=> id: 1, title: "Moby Dick"
user1.books.first.destroy
user1.books.first
=> nil
books.all
=> id: 1, title: "Moby Dick"
user2.books.first
=> id: 1, title: "Moby Dick"
user2.books.first.destroy
=> nil
books.all
=> nil
アップデート
これらの回答に基づいて、おそらく私はあまり明確ではありませんでした. もう一度試してみましょう... book コントローラーには、次の基本的な CRUD create メソッドがあります。
def create
current_user.books.create(name: params[:book][:title])
has_many による関連付けが現在設定されている方法では、ブックが一意である場合にのみ作成されます。すでにシステムにある場合は、false を返します。私がやりたいことは、あたかも新しいレコードであるかのように、既存の本との関連付けを作成することです。これは、これを達成するためにアプリケーションで現在行っていることですが、間違っていると感じています。
def create
book = Book.where(name: params[:book][:title]).first_or_create!
BookReference.where(book_id: book.id, user_id: current_user.id).first_or_create!
2 つ目の問題は、ユーザーが自分のアカウントから書籍を削除した場合です。従来の CRUD destroy を実行すると、すべてのアカウントから削除されます。
def destroy
book = current_user.books.find(params[:id])
book.destroy
これを回避するために、私は現在次のことを行っています。繰り返しますが、これは「正しい」とは感じません。
def destroy
book = current_user.books.find(params[:id])
# if book was unique to user
if BookReference.where(book_id: book.id).count == 1
# remove book from system
book.destroy
else
# remove book reference but not book
current_user.books.delete(book)
end
end