首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Arel表关系划分

Arel表关系划分
EN

Stack Overflow用户
提问于 2018-04-26 19:09:33
回答 1查看 349关注 0票数 1

我在PostgreSQL 9.5中使用了Rails 5.1,并且是Arel表的新手。我正在尝试创建一个查询(我希望该查询最终与其他作用域查询链接),它返回所有相关记录与给定输入匹配的记录。

给定一个weekday_ids: [1, 2, 5, 6]数组,只返回具有active time_slots匹配的的给定weekday_ids

模型

代码语言:javascript
复制
class Range < ApplicationRecord
  has_many :time_slots
end

class TimeSlot < ApplicationRecord
  belongs_to :range
  belongs_to :weekday
end

返回预期结果的工作示例

代码语言:javascript
复制
def self.qualified_time_slots(weekday_ids = nil)
  weekday_ids ||= [1, 2, 5, 6]

  qualified_ranges = Range.includes(:time_slots).all.map do |range|
    active_time_slots = range.time_slots.where(active: true)
    range if weekday_ids.all? { |day| active_time_slots.map(&:weekday_id).include? day }
  end

  # return
  qualified_ranges.compact
end

当前在Arel查询中不工作的尝试,以实现与上述方法相同的功能。

代码语言:javascript
复制
Range.joins(
  :time_slots
).where(
  time_slots: { active: true }
).where(
  TimeSlot.arel_table[:weekday_id].in(weekday_ids)
)

预期结果

代码语言:javascript
复制
# Should return:
[
  range: {
    id: 1, 
    time_slots: [
      { weekday_id: 1 },
      { weekday_id: 2 },
      { weekday_id: 5 },
      { weekday_id: 6 },
    ]
  },
  range: {
    id: 2, 
    time_slots: [
      { weekday_id: 0 },
      { weekday_id: 1 },
      { weekday_id: 2 },
      { weekday_id: 3 },
      { weekday_id: 4 },
      { weekday_id: 5 },
      { weekday_id: 6 },
    ]
  }
]


# Should NOT return 
[
  range: {
    id: 3, 
    time_slots: [
      { weekday_id: 1 },
      { weekday_id: 2 },
      { weekday_id: 5 },
    ]
  },

  range: {
    id: 4, 
    time_slots: [
      { weekday_id: 0 },
      { weekday_id: 6 },
    ]
  }
]

编辑--在运行过程中,我遵循了Joe关于关系司的文章中的示例,并创建了这个原始的SQL查询,该查询看起来正常,但还没有进行彻底的测试:

代码语言:javascript
复制
ActiveRecord::Base.connection.exec_query("
  SELECT 
    ts.range_id
  FROM 
    time_slots AS ts
  WHERE 
    ts.active = true
  AND 
    ts.weekday_id IN (#{weekday_ids.join(',')})
  GROUP BY 
    ts.range_id 
  HAVING COUNT(weekday_id) >= #{weekday_ids.length};
")
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2018-04-27 01:19:24

我还在测试这个,但它看起来很有效:

代码语言:javascript
复制
Range.joins(
  :time_slots
).where(
  TimeSlot.arel_table[:active].eq(
    true
  ).and(
    TimeSlot.arel_table[:weekday_id].in(
      weekday_ids
    )
  )
).group(
  Range.arel_table[:id]
).having(
  TimeSlot.arel_table[:weekday_id].count(true).gteq(weekday_ids.count)
)
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/50050341

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档