数据库中只应有一本书的实例,但有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
第一个问题是,如果图书已经在系统中,则不会为第二个用户创建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 association的方式,只有在本书唯一时才会创建该书。如果它已经在系统中,它将返回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 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
答案 0 :(得分:0)
我对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()
。我不会详细介绍,但我觉得以后你会想要一个自动完成功能来查阅书籍。
在Autocomplete上查看此railscast。 Ryan Bates在设置自动填充功能方面表现出色,如果找不到则会创建新条目,这正是您所寻找的。 p>
此外,如果您需要一种更简单的方法来允许用户添加多本图书,那么这是另一个教您了解Token Fields
的轨道广播答案 1 :(得分:0)
rails会自动为您创建bookreference。
有很多人通过在你的用户模型中创建一个名为: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 %>
应自动填充您的bookreference,您可以在视图中显示它。编辑和销毁也会自动为您完成。当你删除或编辑它时,它只是书籍参考表。
如果您想了解更多关于协会的信息,请访问
并搜索ActiveRecord :: Associations