Join table 有两个复数词。如何正确命名模型和迁移;为了在 join-table 上摧毁孤儿。活动记录
Join table has two plural words. How to properly name models and migrations; in order to destroy orphans on join-table. Active Record
好吧,抛开在聊天板上询问如何 "destroy orphans" 是邪恶的事实,这是我的技术问题:
我正在制作一个简单的博客站点,使用 Activerecord 和 Sinatra(我对这两者都不熟悉)。我在 Post 模型和 Tag 模型之间有一个 "many to many" 关系,并且遇到了我无法解决的错误。最后,我安排了模型和迁移,这样我就不会出错;然而,当我销毁标签的一个实例时,"posts_tags" table 上的关联被留在原地(作为孤儿存在),我想知道如何销毁它们(暗示邪恶的音乐) .
谁能帮我解决这个问题?
这是我对所有三个 table 的迁移:
class CreatePostsTable < ActiveRecord::Migration[5.2]
def change
create_table :posts do |t|
t.string :title, default: 'title here'
t.string :content, default: 'content here'
t.belongs_to :blog, index: true
t.timestamps
end
end
end
class CreateTagTable < ActiveRecord::Migration[5.2]
def change
create_table :tags do |t|
t.string :name, unique: true
end
end
end
class CreatePostsTagsTable < ActiveRecord::Migration[5.2]
def change
create_table :posts_tags, :id => false do |t|
t.belongs_to :tag, index: true
t.belongs_to :post, index: true
# t.integer :post_id
# t.integer :tag_id
end
end
end
这是我的三个模型:
文件名:Post_Tag(我已经命名,并在几天内重新命名了这个 class 和文件名)。
class PostsTag < ActiveRecord::Base
# self.table_name = "posts_tags" #had to add this line for seed file not to give errors
belongs_to :post
belongs_to :tag
end
class Post < ActiveRecord::Base
belongs_to :blog
has_many :posts_tags
has_many :tags, :through => :posts_tags
has_many :comments, dependent: :destroy
end
class Tag < ActiveRecord::Base
has_many :posts_tags
has_many :posts, :through => :posts_tags
# has_and_belongs_to_many :posts, :through => :posts_tags
end
当我搜索 post 的标签或标签的 post 时,此配置不会给我错误,但是当我执行 @tag = Tag.find_by_id(1 ) @tag.destroy "posts_tags" table 仍然保留所有 tag_id == 1 行。当我试图破坏它们时,我得到了错误(我认为这是因为这也会破坏关联)。
有谁知道如何解决这个问题?可以简单地一起删除 PostsTag 模型吗?
Activerecord 文档使用了一个示例,其中 join-table 是一个单词,所以我无法在那里找到答案。
我看到有些人根本就没有为 join-table 制作模型。当我删除我的 join-table 模型时,我得到了这个错误:
@post = Post.find_by_id(1)
@post.tags.each do |tag|
p tag.name
end
NameError at /
uninitialized constant Tag::PostsTag
感谢您的帮助!
#
第二题:
根据提示,我可以尝试将此代码添加到我的模型中:
class Post < ActiveRecord::Base
has_many :posts_tags, dependent: :destroy
class Tag < ActiveRecord::Base
我是 运行 我的 server/app 文件中的这个:
delete "/tag/destroy" do
body = JSON.parse request.body.read # body: {id: number} or {name: string}
@tag_to_destroy = Tag.where(body)[0]
@tag_to_destroy.destroy
redirect "/tag"
end
我正在通过 postman 发送此请求:
http://localhost:4567/tag/destroy
body of request:
{
"id": 12
}
我收到这个错误:
(即使 是 posts_tags 数据库中的行 tag_id = 12,post_id = variousNumbers:
== Sinatra (v2.0.1) 在 Puma 的支持下在 4567 上进行开发
Puma 以单人模式开始...
* 版本 3.11.4 (ruby 2.5.1-p57),代号:情歌
* 最小线程数:0,最大线程数:16
*环境:开发*监听tcp://localhost:4567
使用 Ctrl-C 停止
D、[2018-05-07T10:54:19.604906 #99099] DEBUG -- : 标签加载 (0.5ms) SELECT "tags".* FROM "tags" WHERE "t
ags"."id" = $1 [["id", 12]]
D、[2018-05-07T10:54:19.617955 #99099] 调试——:(0.3 毫秒)开始
D、[2018-05-07T10:54:19.633736 #99099] DEBUG -- : PostsTag Load (1.5ms) SELECT "posts_tags".* FROM "pos
ts_tags" 其中 "posts_tags"."tag_id" = $1 [["tag_id", 12]]
D、[2018-05-07T10:54:19.642305 #99099] 调试——:PostsTag 销毁(1.6 毫秒)从 "posts_tags" 中删除 "posts_tags"。"" IS无效的
D、[2018-05-07T10:54:19.642685 #99099] 调试——:(0.2 毫秒)回滚
2018-05-07 10:54:19 - ActiveRecord::StatementInvalid - PG::SyntaxError:错误:“”“”处或附近的零长度分隔标识符
第 1 行:从 "posts_tags" 中删除 "posts_tags"。"" 为空
^
: 从 "posts_tags" 中删除 "posts_tags"。"" 为空:
/Users/maiya/.rvm/gems/ruby-2.5.1/gems/activerecord-5.2.0/lib/active_record/connection_adapters/postgresql_adapter.rb:603:in `async_exec'
问题更新:
加入-table 迁移以前是:
create_table :posts_tags :id => false do |t|
t.belongs_to :tag, index: true
# comment: the above line creates: t.integer :post_id
t.belongs_to :post, index: true
# comment: the above line creates: t.integer :tag_id
end
现在您的迁移和模型一切正常,您只需更改 Post
和 Tag
模型:
has_many :posts_tags
至
has_many :posts_tags, dependent: :destroy
在这种情况下,在您销毁任何标签或 post 所有关联的 posts_tags 也被销毁后,它将确保您的应用程序的引用完整性并防止错误。
此外,最好回滚迁移,将 foreign_key: true
选项添加到 t.belongs_to
行,然后再次迁移。此选项将提供数据库级别的参照完整性。
更新:
has_and_belongs_to_many
(HABTM) 不适用于 through
选项,您将其与 has_many
关联混在一起。请在 guides
中阅读更多内容
要使其全部正常工作,您需要:
- 从 CreatePostsTagsTable 迁移中删除
:id => false
选项
- 重新迁移或删除并重新创建数据库
- 将 Tag 和 Post 模型中的
has_and_belongs_to_many <...>, :through => :posts_tags
更改为 has_many <...>, :through => :posts_tags
P.S。按照惯例,ruby 中的所有文件名都是小写蛇形,应该是 `posts_tag.rb',而不是 'Posts_Tag.rb'
好吧,抛开在聊天板上询问如何 "destroy orphans" 是邪恶的事实,这是我的技术问题:
我正在制作一个简单的博客站点,使用 Activerecord 和 Sinatra(我对这两者都不熟悉)。我在 Post 模型和 Tag 模型之间有一个 "many to many" 关系,并且遇到了我无法解决的错误。最后,我安排了模型和迁移,这样我就不会出错;然而,当我销毁标签的一个实例时,"posts_tags" table 上的关联被留在原地(作为孤儿存在),我想知道如何销毁它们(暗示邪恶的音乐) .
谁能帮我解决这个问题?
这是我对所有三个 table 的迁移:
class CreatePostsTable < ActiveRecord::Migration[5.2]
def change
create_table :posts do |t|
t.string :title, default: 'title here'
t.string :content, default: 'content here'
t.belongs_to :blog, index: true
t.timestamps
end
end
end
class CreateTagTable < ActiveRecord::Migration[5.2]
def change
create_table :tags do |t|
t.string :name, unique: true
end
end
end
class CreatePostsTagsTable < ActiveRecord::Migration[5.2]
def change
create_table :posts_tags, :id => false do |t|
t.belongs_to :tag, index: true
t.belongs_to :post, index: true
# t.integer :post_id
# t.integer :tag_id
end
end
end
这是我的三个模型:
文件名:Post_Tag(我已经命名,并在几天内重新命名了这个 class 和文件名)。
class PostsTag < ActiveRecord::Base
# self.table_name = "posts_tags" #had to add this line for seed file not to give errors
belongs_to :post
belongs_to :tag
end
class Post < ActiveRecord::Base
belongs_to :blog
has_many :posts_tags
has_many :tags, :through => :posts_tags
has_many :comments, dependent: :destroy
end
class Tag < ActiveRecord::Base
has_many :posts_tags
has_many :posts, :through => :posts_tags
# has_and_belongs_to_many :posts, :through => :posts_tags
end
当我搜索 post 的标签或标签的 post 时,此配置不会给我错误,但是当我执行 @tag = Tag.find_by_id(1 ) @tag.destroy "posts_tags" table 仍然保留所有 tag_id == 1 行。当我试图破坏它们时,我得到了错误(我认为这是因为这也会破坏关联)。
有谁知道如何解决这个问题?可以简单地一起删除 PostsTag 模型吗?
Activerecord 文档使用了一个示例,其中 join-table 是一个单词,所以我无法在那里找到答案。
我看到有些人根本就没有为 join-table 制作模型。当我删除我的 join-table 模型时,我得到了这个错误:
@post = Post.find_by_id(1)
@post.tags.each do |tag|
p tag.name
end
NameError at / uninitialized constant Tag::PostsTag
感谢您的帮助!
#第二题:
根据提示,我可以尝试将此代码添加到我的模型中:
class Post < ActiveRecord::Base
has_many :posts_tags, dependent: :destroy
class Tag < ActiveRecord::Base
我是 运行 我的 server/app 文件中的这个:
delete "/tag/destroy" do
body = JSON.parse request.body.read # body: {id: number} or {name: string}
@tag_to_destroy = Tag.where(body)[0]
@tag_to_destroy.destroy
redirect "/tag"
end
我正在通过 postman 发送此请求:
http://localhost:4567/tag/destroy
body of request:
{
"id": 12
}
我收到这个错误: (即使 是 posts_tags 数据库中的行 tag_id = 12,post_id = variousNumbers:
== Sinatra (v2.0.1) 在 Puma 的支持下在 4567 上进行开发 Puma 以单人模式开始... * 版本 3.11.4 (ruby 2.5.1-p57),代号:情歌 * 最小线程数:0,最大线程数:16 *环境:开发*监听tcp://localhost:4567 使用 Ctrl-C 停止 D、[2018-05-07T10:54:19.604906 #99099] DEBUG -- : 标签加载 (0.5ms) SELECT "tags".* FROM "tags" WHERE "t ags"."id" = $1 [["id", 12]] D、[2018-05-07T10:54:19.617955 #99099] 调试——:(0.3 毫秒)开始 D、[2018-05-07T10:54:19.633736 #99099] DEBUG -- : PostsTag Load (1.5ms) SELECT "posts_tags".* FROM "pos ts_tags" 其中 "posts_tags"."tag_id" = $1 [["tag_id", 12]] D、[2018-05-07T10:54:19.642305 #99099] 调试——:PostsTag 销毁(1.6 毫秒)从 "posts_tags" 中删除 "posts_tags"。"" IS无效的 D、[2018-05-07T10:54:19.642685 #99099] 调试——:(0.2 毫秒)回滚 2018-05-07 10:54:19 - ActiveRecord::StatementInvalid - PG::SyntaxError:错误:“”“”处或附近的零长度分隔标识符 第 1 行:从 "posts_tags" 中删除 "posts_tags"。"" 为空 ^ : 从 "posts_tags" 中删除 "posts_tags"。"" 为空: /Users/maiya/.rvm/gems/ruby-2.5.1/gems/activerecord-5.2.0/lib/active_record/connection_adapters/postgresql_adapter.rb:603:in `async_exec'
问题更新:
加入-table 迁移以前是:
create_table :posts_tags :id => false do |t|
t.belongs_to :tag, index: true
# comment: the above line creates: t.integer :post_id
t.belongs_to :post, index: true
# comment: the above line creates: t.integer :tag_id
end
现在您的迁移和模型一切正常,您只需更改 Post
和 Tag
模型:
has_many :posts_tags
至
has_many :posts_tags, dependent: :destroy
在这种情况下,在您销毁任何标签或 post 所有关联的 posts_tags 也被销毁后,它将确保您的应用程序的引用完整性并防止错误。
此外,最好回滚迁移,将 foreign_key: true
选项添加到 t.belongs_to
行,然后再次迁移。此选项将提供数据库级别的参照完整性。
更新:
has_and_belongs_to_many
(HABTM) 不适用于 through
选项,您将其与 has_many
关联混在一起。请在 guides
要使其全部正常工作,您需要:
- 从 CreatePostsTagsTable 迁移中删除
:id => false
选项 - 重新迁移或删除并重新创建数据库
- 将 Tag 和 Post 模型中的
has_and_belongs_to_many <...>, :through => :posts_tags
更改为has_many <...>, :through => :posts_tags
P.S。按照惯例,ruby 中的所有文件名都是小写蛇形,应该是 `posts_tag.rb',而不是 'Posts_Tag.rb'