Ruby / Rails 3:如何在AR中使用多个嵌套包含查询?

时间:2011-10-25 17:09:16

标签: ruby-on-rails-3 activerecord

* 编辑: *添加最后一段以简要描述问题集 - 数据模型很复杂,但问题集似乎决定了它。也许别人有更好的主意!

我一直在研究这个问题一个多月了,因为我一直在学习Ruby on Rails,而我还没有找到解决方案。我正在使用Rails 3.09,Ruby 1.9.2和PG SQL 8.0。由于gem依赖,我目前无法升级到Rails 3.1。

我有一个复杂的游戏数据模型,涉及收集有关游戏中雇员活动的谣言,并向最终用户显示谣言的内容。当用户选择雇佣时,他们应该能够查看数据库中的所有谣言,其中该雇佣人员是谣言的行动者或行动目标。

以下是有问题的查询:

@rumorEvents = current_webuser.player.rumor_events.includes(:rumor_instances =>[:actor, :target]).where(
            "(hirelings.id=? AND ( (\"suspectedActor\"=hirelings.name) OR (\"suspectedTarget\"=hirelings.name)))", 
            session[:selectedHireling]).
            paginate(:page => params[:page], :per_page => 1).order('"rumor_instances".updated_at DESC')

如上所述,此查询返回会话[:selectedHireling]为演员的所有谣言事件,但不会返回其作为目标的谣言事件。如果我改变         包括(:rumor_instances => [:演员,:目标]) 至         包括(:rumor_instances => [:target]) 它将返回他作为目标的所有事件,但不是演员。

如何为演员和目标返回所有谣言事件?

以下是模型的相关部分:

class RumorEvent < ActiveRecord::Base
belongs_to :player
has_many :rumor_event_rumor_instance_rels, :dependent => :destroy
has_many :rumor_instances, :through => :rumor_event_rumor_instance_rels
    suspectedActor       :string(255)
    suspectedTarget      :string(255)


class RumorInstance < ActiveRecord::Base
belongs_to :player
belongs_to :game_event
has_one :rumor_actor_rel, :dependent => :destroy
has_one :actor, :through => :rumor_actor_rel, :source => :hireling
has_one :rumor_target_rel, :dependent => :destroy
has_one :target, :through => :rumor_target_rel, :source => :hireling

class Hireling < ActiveRecord::Base
#  id                   :integer         not null, primary key
#  name                 :string(255)

所有相关模型都是基本的,并且已知有效。这是一个例子:

# Table name: rumor_event_rumor_instance_rels
#
#  id                :integer         not null, primary key
#  rumor_event_id    :integer
#  rumor_instance_id :integer
#  created_at        :datetime
#  updated_at        :datetime
#

class RumorEventRumorInstanceRel < ActiveRecord::Base
belongs_to :rumor_event
belongs_to :rumor_instance
end

关于游戏事件口头描述的谣言(来自设计师)。

当游戏事件发生时,会存储关于该行为的100%准确且完整的信息,并在3个游戏日内保持可用。当Hirelings and Players访问活动地点附近的城市时,他们将能够学习有关该事件的部分信息(谣言实例),其范围从“有人被暗杀”到“威尼斯商人,Sir Sellsalot先生被Malagant暗杀,一名为(球员)布朗先生服务的雇主。玩家可以从多个来源收集关于同一事件的多个谣言实例,每个来源具有不同级别的信息和不同的准确度(在某些情况下包括虚假信息)。

上面的代码说明了信息的“顶级”,它充当了有关特定事件的所有信息部分(谣言实例)的容器。

1 个答案:

答案 0 :(得分:0)

我没有一个类似场景的项目要测试。然而,在我的头脑中,包含关系的标签是累积的。您应该只能包含2个包含标记:

includes(:rumor_instances => :target).includes(:rumor_instances => :actor)

我认为可能还有别的东西。您的数据模型令人费解。在我看来,一个玩家应该能够通过谣言直接进入谣言实例(我认为这似乎是一个不好的名称)。你正在做的事情很复杂,我觉得你的数据模型有些不对劲。无论哪种方式,希望这会有所帮助。