【问题标题】:ActiveRecord fetching records from has_many and related relationship through scopesActiveRecord 通过范围从 has_many 和相关关系中获取记录
【发布时间】:2016-12-19 12:29:56
【问题描述】:

我有两个模型:CustomerOrder。有时会发生两个客户实际上是同一个客户,这由其中一个具有指向另一个客户记录的master_id 表示。在为客户获取订单时,我还想从奴隶客户那里获取订单(即声称我要查询的客户是他们的主客户记录的客户)。

所以:

Customer1: id: 1, master_id: nil, orders: [Order1, Order2]

Customer2: id: 2, master_id: 1, orders: [Order3]

查询 Customer1.all_orders 应该返回所有 3 个 Order 对象

我知道如何通过一种方法来做到这一点 - 提取奴隶客户的 id,将原始客户的 id 添加到数组中,然后查找 customer_id 在此数组中的订单:

has_many :slave_records, class_name: 'Customer', foreign_key: 'master_id'

def all_orders
  order_ids = slave_records.map(&:id).push(id)
  Order.where(customer_id: order_ids)
end

但是有没有办法使用范围和关系来做到这一点?它是 Rails 4(我知道 Rails 5 应该在它的 ActiveRecord 版本中有一个 OR 的东西)。

【问题讨论】:

  • 如果您能粘贴您目前已实现的部分代码,将会很有帮助
  • @usmanali 我已经添加了我已经实现的方法 - 我想使用范围和关系来实现它
  • 你能试试这个scope: :all_orders -> { [orders, slave_records.map(&:orders)].flatten }吗?
  • @31piy 这不起作用,因为范围 - 就像你提到的那样 - 适用于关系,而不是单个对象,因此在这种情况下 customer_1.all_orders 返回错误 undefined method all_orders' for #`

标签: mysql ruby-on-rails activerecord


【解决方案1】:

在 Order 模型中添加范围会让你更接近你想要的。

class Order
  scope :for_master, -> (master) { where("customer_id = #{master.id} OR customer_id IN (?)", master.slave_records.select(:id)) }
end

因此,对于任何主客户,调用范围,您也将获得儿童订单。

Order.for_master(customer)

您将无法拨打customer.all_orders。但是,您将能够以更简洁的方式获得所有结果。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-02-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多