Ruby Activerecord/Datamapper-有一个子项属于多个父项
如何为以下场景设置activerecord/datamapper关联: 用户创建了一个“书架”,其中有许多书籍(一个book对象只有一个用于查询api的isbn,Ruby Activerecord/Datamapper-有一个子项属于多个父项,ruby,ruby-on-rails-4,activerecord,datamapper,ruby-datamapper,Ruby,Ruby On Rails 4,Activerecord,Datamapper,Ruby Datamapper,如何为以下场景设置activerecord/datamapper关联: 用户创建了一个“书架”,其中有许多书籍(一个book对象只有一个用于查询api的isbn,有许多与之关联的查看对象)。假设Jack用一个book对象创建了一个“书架”。然后,假设Jill用相同的book对象创建了一个“书架”(它有相同的id和相同的评论)。截至目前,book对象具有以下代码: class Book < ActiveRecord::Base has_many :reviews end classbo
有许多与之关联的查看对象)。假设Jack用一个book对象创建了一个“书架”。然后,假设Jill用相同的book对象创建了一个“书架”(它有相同的id和相同的评论)。截至目前,book对象具有以下代码:
class Book < ActiveRecord::Base
has_many :reviews
end
classbook
然后,当您查看一本书的页面时(您单击从Jack创建的“bookshelf”指向该页面的链接),当您从Jill的“bookshelf”单击指向该页面的链接时,您应该会看到相同的book对象(例如,两个“bookshelf”都有指向/books/23的链接,因为它们具有相同的book对象)
我无法通过has\u many
关联来理解这一点,因为这要求我在每次用户向他们的“书架”添加一本书时都要制作一本新书。我很难理解has\u和\u属于\u many
的关系,这是应该在这里使用的吗?我找不到任何类似的问题,所以非常感谢您的帮助
我将Rails4与Ruby2.1结合使用
以下是我想要完成的工作:
是的,您必须定义书架和书籍之间的多对多关系。有两种方法可以在Rails中实现这一点:
选项1)使用具有且属于多个
根据官方文件拥有且属于多个协会:
指定与其他类的多对多关系。这将通过中间联接表关联两个类。除非将联接表显式指定为选项,否则将使用类名的词法顺序猜测联接表。因此,开发人员和项目之间的联接将给出默认联接表名“developers\u projects”,因为按字母顺序“D”在“P”之前
因此,您的类应该如下所示:
class Bookshelf < ActiveRecord::Base
has_and_belongs_to_many :books
end
class Book < ActiveRecord::Base
has_and_belongs_to_many :bookshelves
has_many :reviews
end
class Bookshelf < ActiveRecord::Base
has_many :books, through: :books_bookshelves
has_many :books_bookshelves
end
class Book < ActiveRecord::Base
has_many :bookshelves, through: :books_bookshelves
has_many :books_bookshelves
has_many :reviews
end
class BooksBookshelf < ActiveRecord::Base
belongs_to :book
belongs_to :bookshelf
end
使用has_many:through association
的最好方法可能是允许您向联接表中添加自定义列(例如,添加列count
以跟踪书架中有多少相同类型的书籍)
迁移看起来与我们在选项1中使用的迁移几乎相同,只是我们在外键上添加了一个唯一的约束(请注意,添加约束是可选的):
class CreateBooksheelvesJointable
使用这种方法,添加一个新记录会有点复杂,因为您必须确保没有在联接表中插入重复的记录。(但是,您可以从迁移中删除唯一约束,以实现与使用has\u和\u beliens\u to \u many
时完全相同的行为)
class Bookshelf < ActiveRecord::Base
has_many :books, through: :books_bookshelves
has_many :books_bookshelves
end
class Book < ActiveRecord::Base
has_many :bookshelves, through: :books_bookshelves
has_many :books_bookshelves
has_many :reviews
end
class BooksBookshelf < ActiveRecord::Base
belongs_to :book
belongs_to :bookshelf
end
class CreateBooksBookshelvesJoinTable < ActiveRecord::Migration
def change
create_table :books_bookshelves, id: false do |t|
t.belongs_to :book, index: true
t.belongs_to :bookshelf, index: true
# add your custom columns here
end
add_index :books_bookshelves, [:book_id, :bookshelf_id], unique: true # to make sure you won't create duplicate records
end
end