【问题标题】:Combine many scopes组合多个范围
【发布时间】:2017-11-09 10:44:49
【问题描述】:

我想在我的模型中组合两个不同的范围。我有这个:

后模型

scope :with_tasks, -> { where(cat: 3).includes(:user).includes(task: :users) }
scope :with_events, -> { where(cat: 4).includes(:user).includes(event: :users) }
scope :with_comments, -> {where(comented: true).includes(comments: :user)}

后控制器

def index 
  @posts = current_user.posts.with_tasks + current_user.posts.with_events
end 

但我认为这不是一个真正优雅的实现方式,我不能包含 cmets 范围。

你知道将这个作用域加入一个新作用域的方法吗(如下例所示)?

scope :with_elements, -> { self.with_tasks.merge(self.with_events) }

什么可以让我将此方法调用到我的post#index

@posts = current_user.posts.with_elements

【问题讨论】:

  • 您是否尝试过像current_user.posts.with_tasks.with_events 那样将它们链接起来?
  • 问题是这是两种不同的猫,所以我需要合并它们
  • 你为什么要把where(cat: 3)硬编码到你的范围内?
  • 另一个代码味道是where(comented: true) - 不要为此使用布尔列。使用关联计数或 LEFT INNER JOIN 排除连接表中没有匹配的行。 joins(:comments) 会给你一个内部连接。

标签: ruby-on-rails ruby scope


【解决方案1】:
TASKS = 3
EVENTS = 4
scope :with_tasks_and_or_events, ->(cat) { 
  cond = {}.tap do |c|
    c.merge!(task: :users) if cat.include? TASKS
    c.merge!(event: :users) if cat.include? EVENTS
  end

  where(cat: cat).includes(:user).includes(**cond)
}

并像这样使用它:

with_tasks_and_or_events([TASKS])
with_tasks_and_or_events([TASKS, EVENTS])

或者,更好的是,使用Relational Algebra

或者,更好的是,修改您的数据库结构。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-09-23
    • 2015-05-26
    • 1970-01-01
    • 2015-01-23
    • 2019-04-18
    • 2021-02-24
    • 1970-01-01
    相关资源
    最近更新 更多