【问题标题】:using scope on an association在关联上使用范围
【发布时间】:2011-06-19 01:10:13
【问题描述】:

所以我有一个疯狂的想法,我想将一个范围应用于包含的关联。这是我想出来的,它似乎工作得很好:

class Event < ActiveRecord::Base
  has_many :races
  has_many :bad_races, :conditions => Race.bad_medals_sql, :class_name => "Race"
end

class Race < ActiveRecord::Base
  def self.bad_medals_sql
    arel_table[:prizes].eq('medals').to_sql
    # This returns a string
    # "`races`.`prizes` = 'medals'"
  end

  def self.bad_medals
    where(bad_medals_sql)
  end
end

Event.includes(:bad_races)
Reloading...
  Event Load (0.4ms)  SELECT `events`.* FROM `events`
  Race Load (0.5ms)  SELECT `races`.* FROM `races` WHERE (`races`.event_id IN (1,2,3,4) AND (`races`.`prizes` = 'medals'))

问题是它真的很钝。为了在 Race 上定义范围(在其他地方使用)并在 Event 的关联中使用它,我必须在 Race 上有两种方法。对于每个范围。

我确信我可以将模式包装到插件或类似的东西中,但如果可能的话,我更愿意使用原生 AR/ARel。有什么想法吗?

【问题讨论】:

  • 不要挖掘死帖,但你不必在 Arel 上调用 to_sql,事实上不应该;直接在where条件下使用即可

标签: ruby-on-rails-3 activerecord arel


【解决方案1】:

这段代码似乎过于复杂。假设您的目标是获得所有包含比赛的赛事,而这些赛事只有“奖牌”作为奖品,那么简单的scope 不工作吗?

class Event < ActiveRecord::Base
  has_many :races
  scope :bad_races, includes(:races).where("races.prizes=?", "medals")
end

class Race < ActiveRecord::Base
  belongs_to :event
end

然后你可以运行 Event.bad_races 来获得糟糕的比赛。

【讨论】:

  • “所以我有一个疯狂的想法,我想将范围应用于包含的关联。”
  • AFAIK 你可以通过将bad 设置为Race 的作用域来干掉这段代码,然后直接说races.bad。或者它只适用于范围,我没有检查过:(
  • @AlexeiAverchenko 但是在这种情况下,他想要比赛满足条件的事件(即他不仅想要 Race 对象,他想要它们所属的 Event 对象)。
【解决方案2】:

您可以通过merge 方法在两个模型上使用范围。在这种情况下真的很方便:

class Event < ActiveRecord::Base
  has_many :races
  scope :bad_races, -> { joins(:races).merge(Race.bad_medals) }
end

class Race < ActiveRecord::Base
  belongs_to :event
  scope :bad_medals, -> { where(price: 'medal') }
end

【讨论】:

    【解决方案3】:

    表达您的协会范围的最新方式如下:

    scope :bad_races, -> { joins(:races).where(races: { prizes: 'medals' }) }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-12-22
      • 2015-07-15
      • 2013-06-09
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多