Rails 的自定义加入 Table 名称
Custom Join Table Name for Rails
我是 Rails 上 Ruby 的新手,我正在开发后端 API。
目前,我有 2 个 Active Record 模型,名为 Book 和 User。
活动记录模型
class Book < ActiveRecord::Base
has_and_belongs_to_many :users
end
class User < ActiveRecord::Base
has_and_belongs_to_many :books
end
数据库模式模型
create_table :books do |t|
t.string "title"
end
create_table :users do |t|
t.string "name"
end
#User favourite books
create_join_table :users, :books do |t|
t.index [:user_id, :book_id]
t.index [:book_id, :user_id]
end
#User read books
create_join_table :users, :books do |t|
t.index [:user_id, :book_id]
t.index [:book_id, :user_id]
t.integer "read_pages"
t.string "status"
t.integer "rating"
t.datetime "start_date"
t.datetime "finish_date"
end
问题
我想创建 2 加入 tables,其中一个用于添加到用户 收藏夹 列表的那些书, 另一本用于用户 阅读.
的书籍
两个 table 共享 user_id & book_id,然而,第二个有更多的数据,因为它是一条记录。
- Active Record 命名约定自动创建一个名为 users_books 的 table。所以当我迁移它时,它向我报告以下错误:
Index name 'index_books_users_on_user_id_and_book_id' on table 'books_users' already exists
- 如何重命名第二个连接 table 名称?
如果要为 many to many
关系保存 primary
以外的键,则应使用 has_many :through
关联。有关详细信息,请参阅 Rails guides。您的模型应如下所示:
class Book < ActiveRecord::Base
has_many :read_books
has_many :users, through: :read_books
end
class User < ActiveRecord::Base
has_many :read_books
has_many :books, through: :read_books
end
class ReadBook < ActiveRecord::Base
belongs_to :user
belongs_to :book
end
你也可以在 read_books
中制作一个 field/flag(is_favourite)
并在 read_books 中为
这样的收藏夹创建一个范围
scope :favourites, -> { where(is_favourite: true) }
How do I rename the second join table name?
传递 table_name:
选项:
create_join_table :users, :books, table_name: :favorite_books do |t|
t.index [:user_id, :book_id]
end
您还需要为关联使用唯一的名称并告诉 rails 发生了什么,因为它可以从名称派生:
class User < ApplicationRecord
has_and_belongs_to_many :books
has_and_belongs_to_many :favorite_books,
join_table: 'favorite_books',
class_name: 'Book',
inverse_of: :favorite_books
end
class Book
has_and_belongs_to_many :users
# for lack of a better name?
has_and_belongs_to_many :favorite_users,
join_table: 'favorite_books',
class_name: 'User',
inverse_of: :favorite_books
end
唯一的名称是必要的,因为如果您使用相同的名称,您只会破坏以前的关联。
但是...
has_and_belongs_to_many
和 create_join_table
非常无用,因为它们不允许您访问 table 上的任何其他列,并且不提供诸如主键或时间戳。文档说:
Use has_and_belongs_to_many when working with legacy schemas or when you never work directly with the relationship itself.
但是您怎么知道您是否想要这些功能呢?而你被困在那里只有两个外键的 table 。如果内存使用成为问题(这不会发生),那么使用 has_many through:
并切换到 has_and_belongs_to_many
是一个更好的主意。
TLDR; has_and_belongs_to_many
糟透了。请改用 has_many through:
。
我是 Rails 上 Ruby 的新手,我正在开发后端 API。
目前,我有 2 个 Active Record 模型,名为 Book 和 User。
活动记录模型
class Book < ActiveRecord::Base
has_and_belongs_to_many :users
end
class User < ActiveRecord::Base
has_and_belongs_to_many :books
end
数据库模式模型
create_table :books do |t|
t.string "title"
end
create_table :users do |t|
t.string "name"
end
#User favourite books
create_join_table :users, :books do |t|
t.index [:user_id, :book_id]
t.index [:book_id, :user_id]
end
#User read books
create_join_table :users, :books do |t|
t.index [:user_id, :book_id]
t.index [:book_id, :user_id]
t.integer "read_pages"
t.string "status"
t.integer "rating"
t.datetime "start_date"
t.datetime "finish_date"
end
问题
我想创建 2 加入 tables,其中一个用于添加到用户 收藏夹 列表的那些书, 另一本用于用户 阅读.
的书籍两个 table 共享 user_id & book_id,然而,第二个有更多的数据,因为它是一条记录。
- Active Record 命名约定自动创建一个名为 users_books 的 table。所以当我迁移它时,它向我报告以下错误:
Index name 'index_books_users_on_user_id_and_book_id' on table 'books_users' already exists
- 如何重命名第二个连接 table 名称?
如果要为 many to many
关系保存 primary
以外的键,则应使用 has_many :through
关联。有关详细信息,请参阅 Rails guides。您的模型应如下所示:
class Book < ActiveRecord::Base
has_many :read_books
has_many :users, through: :read_books
end
class User < ActiveRecord::Base
has_many :read_books
has_many :books, through: :read_books
end
class ReadBook < ActiveRecord::Base
belongs_to :user
belongs_to :book
end
你也可以在 read_books
中制作一个 field/flag(is_favourite)
并在 read_books 中为
scope :favourites, -> { where(is_favourite: true) }
How do I rename the second join table name?
传递 table_name:
选项:
create_join_table :users, :books, table_name: :favorite_books do |t|
t.index [:user_id, :book_id]
end
您还需要为关联使用唯一的名称并告诉 rails 发生了什么,因为它可以从名称派生:
class User < ApplicationRecord
has_and_belongs_to_many :books
has_and_belongs_to_many :favorite_books,
join_table: 'favorite_books',
class_name: 'Book',
inverse_of: :favorite_books
end
class Book
has_and_belongs_to_many :users
# for lack of a better name?
has_and_belongs_to_many :favorite_users,
join_table: 'favorite_books',
class_name: 'User',
inverse_of: :favorite_books
end
唯一的名称是必要的,因为如果您使用相同的名称,您只会破坏以前的关联。
但是...
has_and_belongs_to_many
和 create_join_table
非常无用,因为它们不允许您访问 table 上的任何其他列,并且不提供诸如主键或时间戳。文档说:
Use has_and_belongs_to_many when working with legacy schemas or when you never work directly with the relationship itself.
但是您怎么知道您是否想要这些功能呢?而你被困在那里只有两个外键的 table 。如果内存使用成为问题(这不会发生),那么使用 has_many through:
并切换到 has_and_belongs_to_many
是一个更好的主意。
TLDR; has_and_belongs_to_many
糟透了。请改用 has_many through:
。