我有模型Account和User. 兩個模型都有一個email屬性。
一個帳戶has_many :users和一個用戶belongs_to :account
我想在創建emailan 時驗證兩個模型的唯一性,Account因此Account如果電子郵件被 a 接收,則該電子郵件無效User(因為帳戶電子郵件后來成為管理員用戶電子郵件)。
我email在Account模型中為約束添加了一個范圍,但它不起作用(表單沒有被拒絕)。
賬戶模式:
has_many :users
validates :email, uniqueness: { scope: :users, case_sensitive: false }
實作這一點的正確方法是什么?我需要向資料庫添加索引嗎?
uj5u.com熱心網友回復:
這是一種基于單獨表和多型關聯的替代方法:
class CreateEmailAddresses < ActiveRecord::Migration[6.1]
def change
create_table :email_addresses do |t|
t.string :email, unique: true
t.references :entitity, polymorphic: true
t.timestamps
end
add_index :email_addresses, [:entity_type, :entity_id], unique: true
end
end
class EmailAddress < ApplicationRecord
validates_uniqueness_of :email
validates_uniqueness_of :entity_id, scope: :entity_type
belongs_to :entity, polymorphic: true
end
class User < ApplicationRecord
has_one :email_address,
as: :entity,
dependent: :destroy
delegate :email, to: :email_address
accepts_nested_attributes_for :email_address
end
class Account < ApplicationRecord
has_one :email_address,
as: :entity,
dependent: :destroy
delegate :email, to: :email_address
accepts_nested_attributes_for :email_address
end
它避免了為了創建電子郵件而必須重構域或創建用戶,但會導致身份驗證庫(例如 Devise)出現問題,并且缺少真正的外鍵來保證參考完整性,這可能導致孤立記錄。
IMO 不是一個很好的解決方案,因為它很可能會產生與它解決的問題一樣多的問題。
uj5u.com熱心網友回復:
這只能通過
由于無法 (AFAIK) 跨表創建索引,因此您可能只想重組域并向帳戶表添加“所有者”(隨意命名):
class AddOwnerToAccounts < ActiveRecord::Migration[6.1]
def change
add_reference :accounts, :owner, null: false, foreign_key: { to_table: 'users' }
end
end
class Account < ApplicationRecord
has_many :users
belongs_to :owner,
class_name: 'User',
inverse_of: :owned_accounts
delegate :email, to: :owner
end
class User < ApplicationRecord
belongs_to :account
has_many :owned_accounts,
class_name: 'Account',
foreign_key: :owner_id,
inverse_of: :owner
end
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/366135.html
