问题描述
我正在尝试将几个ID传递给活动管理员的自定义ransacker过滤器
filter :hasnt_purchased_product_items_in,as: :select,collection: -> { ProductItem.all },multiple: true
洗劫者代码
ransacker :hasnt_purchased_product_items,formatter: proc { |product_id|
users_who_purchased_ids = User.joins(:orders => :items).where("orders.status = 'success'").where("order_items.orderable_id IN (?)",product_id) # return only id-s of returned items.
ids = User.where.not(id: users_who_purchased_ids).pluck(:id)
ids.present? ? ids : nil # return ids OR nil!
} do |parent| # not sure why this is needed .. but it is :)
parent.table[:id]
end
这适用于单个查询,但不适用于多个查询,sql会进行2次单独的搜索,而不是一次。
它正在运行以下2条语句
order.items.orderable_id IN ('90')
和
order.items.orderable_id IN ('91')
在2个单独的sql语句中,而不是我想要的是
order.items.orderable_id IN ('90','91')
活动管理页面中提交的信息是
q[hasnt_purchased_product_items_in][]: 90
q[hasnt_purchased_product_items_in][]: 91
我认为我需要在ransacker阶段对传入参数做些事情,但是我不确定如何处理
解决方法
不应该介入。参数应该是| product_ids |。并在proc中给我们一个数组对象,然后再使用它。您的抢劫犯应该返回一个活动记录关联或一个arel查询。
我将尝试其中的每一个:
- 在抢劫者名称中使用“ _in”,绕过数组逻辑。
ransacker :hasnt_purchased_product_items_in do |product_ids|
users_who_purchased_ids = User.joins(orders: :items).where(orders: {status: 'success'},order_items: {orderable_id: product_ids}) # return only id-s of returned items.
User.where.not(id: users_who_purchased_ids)
end
- 相同的抢劫犯名称,但使用块而不是格式化程序。
ransacker :hasnt_purchased_product_items do |product_ids|
users_who_purchased_ids = User.joins(orders: :items).where(orders: {status: 'success'},order_items: {orderable_id: product_ids}) # return only id-s of returned items.
User.where.not(id: users_who_purchased_ids)
end
我不得不猜测该对象将返回,因为目前尚不清楚此抢劫犯所使用的模型。如果您可以告诉我目标(例如过滤用户的产品推荐以排除他们的购买),那么我可以更新答案。
- 创建范围并将其提供给搜查。
User.rb
scope :hasnt_purchased_product_items_in,->(product_ids){
users_who_purchased_ids = joins(orders: :items).where(orders: {status: 'success'},order_items: {orderable_id: product_ids}) # return only id-s of returned items.
where.not(id: users_who_purchased_ids)
}
def self.ransackable_scopes(auth_object = nil)
%i(hasnt_purchased_product_items_in)
end
然后这有效:
User.ransack({hasnt_purchased_product_items_in: [[1,2,3]]}).result
请注意,背包需要一个args数组。我们需要一个arg,它是一个数组。