【问题标题】:Issues chaining scopes in Rails with context在 Rails 中使用上下文链接范围的问题
【发布时间】:2015-11-25 10:20:09
【问题描述】:

我有 4 个模型:Artists, Editions, Events & EventItems

  • 版本有很多事件
  • 事件通过 EventItems 有很多艺术家
  • 各版本通过活动有许多艺术家

关于艺术家我有一个范围published

我将活跃定义为参加活动的艺术家,其状态不是draft

scope :published, -> { joins(:events).where("events.state != ?", 'draft').uniq }

这很好用,直到我开始链接它们并希望艺术家在给定版本中至少有 published 的事件。

Edition.first.artists.published

除了它还会加入当前版本之外的events,并且如果艺术家发布了任何事件(即使他们不在此特定版本中),则会错误地发布艺术家。

为了让它正常工作,我不得不像这样破解它(这太可怕了):

  scope :published, ->(edition = nil) {
    if edition.present?
      joins(:events).where("events.state != ? AND events.edition_id = ?", 'draft', edition.id).uniq
    else
      joins(:events).where("events.state != ?", 'draft').uniq
    end
  }

Edition.first.artists.published(Edition.first)

是否有更多的上下文来说明这个版本中只包含这些事件的范围?那么它的范围会正确吗?

谢谢!

【问题讨论】:

    标签: ruby-on-rails ruby-on-rails-4 ruby-on-rails-4.2 named-scope scopes


    【解决方案1】:

    恕我直言,问题取决于您的关联和您正在生成的 SQL,而不是您应该如何为范围提供上下文(传递参数是完全合法的)。

    调用Event.artists 时,您已经通过has_many :artists, through: :events 加入了活动,并且通过该活动不加选择地加入events。最重要的是,您依靠事件来确定艺术家是否活跃,如果不是违反 SRP,这也是另一个混​​乱的来源。

    我认为解决方案来自于定义正确的关联:

    class Edition
      has_many :events
      has_many :artists, through: :events
    
      has_many :active_events, -> {where.not(state: "draft")}, class_name: "Events"
      has_many :active_artists, through: :active_events, 
                class_name: "Artist", 
                source: :artists # => not sure if this option is necessary
    end
    
    class Events
      has_many :event_items
      has_many :artists, through: :event_items
    end 
    
    Event.first.active_artists
    

    我不是 100% 确定宏选项,但你明白了。

    【讨论】:

      猜你喜欢
      • 2017-07-29
      • 2016-04-29
      • 1970-01-01
      • 2018-05-31
      • 2012-09-23
      • 2020-11-01
      • 2019-01-25
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多