我想你要去宣佈他們錯了,因爲這應該正常工作。這就是:through
指令是什麼:
class User < ActiveRecord::Base
has_many :event_countries
has_many :countries_with_events,
:through => :event_countries,
:source => :country
has_many :research_countries
has_many :countries_with_researches,
:through => :research_countries,
:source => :country
end
class EventCountry < ActiveRecord::Base
belongs_to :country
belongs_to :user
end
class ResearchCountry < ActiveRecord::Base
belongs_to :country
belongs_to :user
end
class Country < ActiveRecord::Base
# ...
end
很多的尷尬來自於你所選擇的表的標籤。雖然乍看起來似乎是合理的,但是使用它們的方式最終會使它們變得困難。
您可能需要調用research_countries
像user_research_countries
,這樣的關係名稱可以是user.research_countries
作爲:through
:
class User < ActiveRecord::Base
has_many :user_event_countries
has_many :event_countries,
:through => :user_event_countries,
:source => :country
has_many :user_research_countries
has_many :research_countries,
:through => :user_research_countries,
:source => :country
end
class UserEventCountry < ActiveRecord::Base
belongs_to :country
belongs_to :user
end
class UserResearchCountry < ActiveRecord::Base
belongs_to :country
belongs_to :user
end
class Country < ActiveRecord::Base
# ...
end
您可以通過添加一個字段用戶國家關聯表進一步重構這一點,包括一個或多個旗幟,在這種情況下,這將是研究或事件或任何您需要以後:
class User < ActiveRecord::Base
has_many :user_countries
has_many :event_countries,
:through => :user_countries,
:source => :country,
:conditions => { :event => true }
has_many :research_countries,
:through => :user_countries,
:source => :country,
:conditions => { :research => true }
end
class UserCountry < ActiveRecord::Base
belongs_to :country
belongs_to :user
# * column :event, :boolean
# * column :research, :boolean
end
class Country < ActiveRecord::Base
# ...
end
真棒的答案。我同意你提到的命名約定。其實這是他們在我的應用程序是如何創建的,但我縮短了它的問題。對於如何重構這也是一個很好的建議。不知道是否比只有「研究」或「事件」的類型列更好,但我想你可以使用該方法可能會導致一些(很少)重複的數據。 – Tony 2010-11-16 16:20:34
在有關用戶和國家的單個表中有N個布爾列可能比有N個關係表的效率高很多。作爲副作用,這也使得查找用戶在同一個國家進行事件並進行研究的情況更容易。 – tadman 2010-11-16 17:30:24