更新:這可能是不可行的。 See this包含一個關聯,如果它存在於rails查詢中
TLDR:您如何有條件地加載關聯(比如只加載當前用戶的關聯),同時還包括根本沒有關聯的記錄?
Rails 3.1,這裏大概是我正在使用的模型。
class User
has_many :subscriptions
has_many :collections, :through => :subscriptions
end
class Collection
has_many :things
end
class Thing
has_many :user_thing_states, :dependent => :destroy
belongs_to :collection
end
class Subscription
belongs_to :user
belongs_to :collection
end
class UserThingState
belongs_to :user
belongs_to :thing
end
有很多收藏品有很多東西。用戶訂閱許多集合,因此他們訂閱很多東西。用戶具有與事物相關的狀態,但不一定,並且仍然訂閱事物,即使它們沒有發生狀態。當用戶訂閱一個集合及其關聯的東西時,不會爲每一件事情(可能會有數百個)生成一個狀態。相反,狀態是在用戶首次與給定事物交互時生成的。現在,問題是:我想在加載狀態所在的每個事物的用戶狀態時選擇用戶的所有訂閱內容。
從概念上講,這並不難。作爲參考,SQL將爲我提供所需的數據是:
SELECT things.*, user_thing_states.* FROM things
# Next line gets me all things subscribed to
INNER JOIN subscriptions as subs ON things.collection_id = subs.collection_id AND subs.user_id = :user_id
# Next line pulls in the state data for the user
LEFT JOIN user_thing_states as uts ON things.id = uts.thing_id AND uqs.user_id = :user_id
我只是不知道如何將它拼湊在一起。 Thing課堂會發生什麼? Thing.includes(:user_thing_states)將加載所有用戶的所有狀態,並且看起來像是唯一的工具。我需要的是這樣的,但我不知道如何(或者如果可能的話):
class Thing
has_many :user_thing_states
delegates :some_state_property, :to => :state, :allow_nil => true
def state
# There should be only one user_thing_state if the include is correct, state method to access it.
self.user_thing_states.first
end
end
我需要這樣的東西:
Thing.includes(:user_question_states, **where 'user_question_state.user_id => :user_id**).by_collections(user.collections)
然後,我可以做
things = User.things_subscribed_to
things.first.some_state_property # the property of the state loaded for the current user.
問題是模型的其他部分是類別和訂閱:用戶訂閱的類別和類別包含很多東西。所以問題是用戶可能通過訂閱與很多東西相關聯,並且他們訂閱的東西集大於他們所處的東西集,因爲只有當用戶第一次與東西交互時才創建狀態。所以我在尋找**用戶訂閱的東西是否有用戶的狀態,但包括用戶的狀態對象(如果存在)** –
您沒有定義任何的概念訂閱作爲模型或模式。我覺得你讓這件事比需要的複雜得多。添加一個如何過濾這個用戶的例子,因爲你似乎偶然發現了這個。 – Winfield
爲了清晰起見,我重寫了原始問題(爲了簡潔起見,我省略了這些問題使其更加混亂),並在解決問題的同時解決問題。去搞清楚。儘管如此,你的更新仍然存在同樣的問題:用戶可以訂閱比他們所擁有的更多的東西,我希望所有這些東西。感謝您的幫助,但通過用戶考慮是很有幫助的。 –