Ransack: how to join table multiple times with different alias?

老子叫甜甜 提交于 2019-12-06 06:52:16

Just use Model.search(params[:q].try(:merge, m: 'or')), using your example:

q: {
  m: 'or',
  g: {
    '0' => { properties_name_eq: 'a_name', properties_value_eq: 'a_value' },
    '1' => { properties_name_eq: 'another_name', properties_value_eq: 'another_value'}
  }
}

You can find more information here

You need an or at the where level of your query, because properties.name can't be equal 'a_name' and 'another_name' at the same time. A second alias for the table is not required.

You can solve this by using multiple queries.

  1. For each name + value property, get all item IDs with this property
  2. Intersect the resulting IDs for each property into item_ids
  3. In the final query on :items, add the clause WHERE id IN (item_ids)

Here's a code example that does steps 1 & 2:

def property_item_ids(conditions)
  conditions.inject([]) do |result, (key, condition)|
    result.method(result.empty? ? '+' : '&').(Property.ransack(m: "and", g: condition).pluck(:item_id).to_a)
  end
end

Get the item IDs that have all properties:

conditions = {
  '0' => { properties_name_eq: 'a', properties_value_eq: 'a1' },
  '1' => { properties_name_eq: 'b', properties_value_eq: 'b1'}
}

item_ids = property_item_ids(conditions)

For step 3, invoke ransack with item_ids:

q: {
  m: 'and',
  g: {
    '0' => { item_id_in: item_ids }
  }
}
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!