我在 Rails(使用 Postgresql)中創建以下表:
User:用戶可以在一個或多個組中,并且可以是一個或多個組的所有者Group:一個組有一個管理員(其中一個用戶)和一個或多個用戶Participant:參與者在其他兩個之間的表連接他們
模型是這樣的:
#User.rb
class User < ApplicationRecord
has_many :groups
has_many :participants
end
#Group.rb
class Group < ApplicationRecord
belongs_to :user
has_many :participants
end
#Participant.rb
class Participant < ApplicationRecord
belongs_to :group
belongs_to :user
end
在此之后,我進行了一些遷移以將其名稱user_id更改Group為admin_id:
class ChangeForeignKeyForGroups < ActiveRecord::Migration[6.1]
def change
rename_column :groups, :user_id, :admin_id
end
end
所以現在,我的schema樣子是這樣的:
create_table "groups", force: :cascade do |t|
t.string "name"
t.text "description"
t.integer "participants"
t.bigint "admin_id", null: false
t.datetime "created_at", precision: 6, null: false
t.datetime "updated_at", precision: 6, null: false
t.index ["admin_id"], name: "index_groups_on_admin_id"
end
create_table "participants", force: :cascade do |t|
t.bigint "group_id", null: false
t.bigint "user_id", null: false
t.datetime "created_at", precision: 6, null: false
t.datetime "updated_at", precision: 6, null: false
t.index ["group_id"], name: "index_participants_on_group_id"
t.index ["user_id"], name: "index_participants_on_user_id"
end
create_table "users", force: :cascade do |t|
t.string "email", default: "", null: false
t.string "encrypted_password", default: "", null: false
t.string "reset_password_token"
t.datetime "reset_password_sent_at"
t.datetime "remember_created_at"
t.datetime "created_at", precision: 6, null: false
t.datetime "updated_at", precision: 6, null: false
t.string "username"
t.index ["email"], name: "index_users_on_email", unique: true
t.index ["reset_password_token"], name: "index_users_on_reset_password_token", unique: true
問題是,一旦我嘗試在種子中創建一個組,我就會一直遇到這個錯誤:
pry(main)> group = Group.new(name: "Test Group", description: "blablabal")
=> #<Group:0x00007fdbcdd03f80 id: nil, name: "Test Group", description: "blablabal", participants: nil, admin_id: nil, created_at: nil, updated_at: nil>
[5] pry(main)> group.valid?
=> false
[6] pry(main)> group.errors
=> #<ActiveModel::Errors:0x00007fdbcdc7ad98
@base=#<Group:0x00007fdbcdd03f80 id: nil, name: "Test Group", description: "blablabal", participants: nil, admin_id: nil, created_at: nil, updated_at: nil>,
@errors=[#<ActiveModel::Error attribute=user, type=blank, options={:message=>:required}>]>
看來我錯過了user,所以我嘗試添加它,但它拋出了同樣的錯誤:
user = User.first
User Load (1.4ms) SELECT "users".* FROM "users" ORDER BY "users"."id" ASC LIMIT $1 [["LIMIT", 1]]
=> #<User id: 7, email: "[email protected]", created_at: "2022-05-31 10:29:06.208673000 0000", updated_at: "2022-05-31 10:29:06.208673000 0000", username: "Jose">
pry(main)> group = Group.new(name: "Test Group", description: "blablabal", admin_id: user.id)
=> #<Group:0x00007fdbdd205ad8 id: nil, name: "Test Group", description: "blablabal", participants: nil, admin_id: 7, created_at: nil, updated_at: nil>
[13] pry(main)> group.valid?
=> false
[14] pry(main)> group.errors
=> #<ActiveModel::Errors:0x00007fdbdd1d4578
@base=#<Group:0x00007fdbdd205ad8 id: nil, name: "Test Group", description: "blablabal", participants: nil, admin_id: 7, created_at: nil, updated_at: nil>,
@errors=[#<ActiveModel::Error attribute=user, type=blank, options={:message=>:required}>]>
難道我做錯了什么?我的結構是否錯誤?謝謝!
uj5u.com熱心網友回復:
你只是重命名了你的外鍵,但還有更多。在我的遷移中,我會做這樣的事情:
class ChangeForeignKeyForGroups < ActiveRecord::Migration[6.1]
def change
remove_reference :groups, :user, foreign_key: true
add_reference :groups, :admin, foreign_key: true
end
end
請注意,我認為您重命名的方式可能也會更改索引和外鍵。所以你可能不需要改變它。
然后在您的group.rb模型中,您需要更改關聯:
belongs_to :admin, class_name: "User", foreign_key: :admin_id
然后,如果你回到你的種子,你可以將你的組創建更改為:
Group.new(name: "Test Group", description: "blablabal", admin: user)
uj5u.com熱心網友回復:
Ruby on Rails 對模型之間的關聯有一定的命名約定。我建議閱讀官方 Rais Guides 中有關 Active Record 關聯的資訊。
例如,如果模型belongs_to :user中有關聯,Group那么 Rails 期望資料庫中的表user_id上有一個列groups指向id名為 的表中的記錄users。
這允許 Ruby on Rails 無需太多配置即可作業,這被稱為約定優于配置。
如果您不想遵循這些約定,則需要配置不遵循此約定的所有內容。在您的示例中,您需要添加foreign_key: 'admin_id'到關聯的兩側,以告訴 Ruby on Rails 您不想使用默認列命名,admin_id而是像這樣:
class User < ApplicationRecord
has_many :participants, foreign_key: 'admin_id'
# ...
class Group < ApplicationRecord
belongs_to :user, foreign_key: 'admin_id'
# ...
由于在非默認命名的情況下需要額外的配置,我強烈建議不要使用自定義表名或外鍵名。并且僅在資料庫架構不受您控制時才使用它們。因此,我建議將重命名從 恢復user_id為admin_id。
轉載請註明出處,本文鏈接:https://www.uj5u.com/caozuo/483823.html
標籤:轨道上的红宝石 红宝石 PostgreSQL 活动记录
