- 作为用户,我可以将我最喜欢的书添加到我的书单中
- 另一个用户将同一本书添加到他们的图书列表中
-
数据库中应该只有一个图书实例,但有两个用户/图书关联。
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
第一个问题是,如果该书已经在系统中,则不会为第二个用户创建bookReference,因为该书不是唯一的
因此,如果书已经在系统中,我只想在bookReference表中创建关联记录。
第二个问题是,当用户删除一本书时,我只希望它删除对该书的引用,除非他们是唯一引用该书的用户
基本上,这是我试图实现的用法的完整概述:
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
更新
根据这些答案,也许我不是很清楚。让我再试一次。。。书籍控制器,有一个基本的CRUD创建方法:
def create
current_user.books.create(name: params[:book][:title])
按照当前设置has_many through关联的方式,只有当图书是唯一的时,才会创建该图书。如果它已经在系统中,它将返回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!
第二个问题是当用户从他们的帐户中删除一本书时。进行传统的CRUD销毁将从所有帐户中删除:
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
rails会自动为您创建图书参考。
在您的用户模型中创建了一个名为:book_ids的"隐藏列">
所以在你的表单中,如果你想"保存"一本书给用户,你会使用
<%= form_for (@user) do |f| %>
.
.
.
<%= f.label :book_ids %>
<%= f.select :book_ids, Book.all.collect {|x| [x.name, x.id]}, {}, :multiple => true %>
您的图书参考应该自动填充,您可以在视图中显示它。编辑和销毁也会自动为您完成。当您删除或编辑时,它将只是图书参考表。
如果你想了解更多关于协会的信息,你可以去
http://api.rubyonrails.org/
并搜索ActiveRecord::Associations
我对rails还是有点陌生,但这就是我想到的。
book = user1.books.first
if book.users.size > 1
user1.books.first.destroy
else
book.destroy
end
# in order to delete the book's dependency, you will need
class Book
has_many :bookReferences, :dependent => :destroy
希望这能有所帮助。
注意:当您有一个名为BookReference
的模型时,您将该模型称为:book_reference
在您的情况下,您需要更改为
class User
has_many :book_references
has_many :books, through: :book_references
class Book
validates_uniqueness_of :title
has_many :book_references
has_many :users, through: :book_references
class BookReference
belongs_to :user
belongs_to :book
更新:
由于您希望新书在数据库中不存在时创建,因此可以利用的rails方法之一是Book.find_or_create()
。我不想详细介绍,但我觉得以后你会想要一个自动完成功能来查找书籍。看看这个关于自动完成的railscast。Ryan Bates在设置自动完成并在找不到新条目时创建新条目方面做得很好,这就是你想要的。
此外,如果您需要一种更简单的方法来允许用户添加多本书,这里有另一个railscast,它会教您有关令牌字段