更新:这可能是不可行的。 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
为了清晰起见,我重写了原始问题(为了简洁起见,我省略了这些问题使其更加混乱),并在解决问题的同时解决问题。去搞清楚。尽管如此,你的更新仍然存在同样的问题:用户可以订阅比他们所拥有的更多的东西,我希望所有这些东西。感谢您的帮助,但通过用户考虑是很有帮助的。 –