[英]Rails model associations, has_many :through and has_one with the same model
我有兩個模型:用戶和狀態。 州模型擁有美國 50 個州中每一個州的記錄。
我希望每個用戶都有兩個屬性:一個是“家”狀態,另一個是“訪問”狀態。
我知道我必須建立某種模型關聯來實現這一點,但不確定最好的方法是什么。
這是我到目前為止所擁有的,但我知道將 has_many 和 has_one 關聯到同一模型肯定有問題。
#user.rb
class User < ActiveRecord::Base
has_many :visits
has_many :states, :through => :visits
has_one :state
end
#visit.rb
class Visit < ActiveRecord::Base
belongs_to :user
belongs_to :state
end
#state.rb
class State < ActiveRecord::Base
has many :visits
has many :users, :through => :visits
belongs_to :user
end
有什么建議?
在我看來,您已經擁有的幾乎是正確的,除非您將主狀態外鍵存儲在用戶上,如下所示:
# user.rb
class User < ActiveRecord::Base
belongs_to :state
has_many :visits
has_many :states, through: visits
end
# visit.rb
class Visit < ActiveRecord::Base
belongs_to :user
belongs_to :state
end
# state.rb
class State < ActiveRecord::Base
has_many :visits
has_many :users, through: :visits
end
然后,您將像這樣訪問主狀態:
u = User.first
u.state
和訪問過的狀態,如下所示:
u = User.first
u.states
為了編程清晰,您可以重命名您的關系:
# user.rb
class User < ActiveRecord::Base
belongs_to :home_state, class_name: "State"
has_many :visits
has_many :visited_states, class_name: "State", through: visits
end
# state.rb
class State < ActiveRecord::Base
has_many :residents, class_name: "User"
has_many :visits
has_many :visitors, class_name: "User", through: :visits
end
您的域模型會更有意義:
u = User.first
u.home_state
u.visited_states
s = State.first
s.residents
s.visitors
我預計您可能希望存儲有關訪問的其他信息,因此保留Visit
模型的 HMT 連接表將允許您執行此操作,而不是使用 HABTM 關系。 然后,您可以向訪問添加屬性:
# xxxxxxxxxxxxxxxx_create_visits.rb
class CreateVisits < ActiveRecord::Migration
def change
create_table :visits do |t|
t.text :agenda
t.datetime commenced_at
t.datetime concluded_at
t.references :state
t.references :user
end
end
end
我希望每個用戶都有兩個屬性:一個是“家”狀態,另一個是“訪問”狀態。
在您的模型中,一個州可能只belongs_to
一個用戶 ( belongs_to
)。
正確的語義是
class User < AR::Base
belongs_to :home_state, :class_name => "State", :foreign_key => "home_state_id", :inverse_of => :users_living
has_and_belongs_to_many :visited_states, :through => :visits
# ...
end
class State < AR::Base
has_many :users_living, :class_name => "User", :inverse_of => :home_state
# ...
end
您不能在單個模型上擁有 has_many 和 has_one 關系,在本例中為 state。 一種解決方案是:
創建狀態的靜態模型,它們不需要是數據庫模型,它們可以是狀態模型上的靜態變量: US_STATES = {'1' => 'AK', '2' => 'AL', etc}
或者因為你需要使用一個rake任務或數據庫,你可以使用fixture狀態的表加載到數據庫中(更復雜:種子任務加載夾具進入分貝,但好的,因為你可以使用活動記錄管理該模型)。
然后您可以在定義 home_state 的用戶模型上提供 home_state_id,訪問只是 user_id 和 state_id 之間的連接。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.