0

I have an array like this

arr = %w[android ios]

and I want to use these values in Where clause in a query like below:

SELECT * FROM controls
WHERE company_id = '12345' AND (ios > 13 OR android > 14)

where the fields inside ( ) are the values of array .. so if i have only one value in array it would be

 WHERE company_id = '12345' AND (ios > 13)

for example

Is it possible using Ruby on rails ActiveRecord?

2
  • Where do you get this 13 and 14 from? Commented Jun 3, 2022 at 0:12
  • this is an arbitrary value .. it could be any number.. it's just for example Commented Jun 3, 2022 at 0:16

3 Answers 3

1

Looks like you need not array but hash like this

more_than = {
  ios: 13,
  android: 14
}

You can build SQL condition string with sanitize_sql_for_conditions from array with placeholders

sql_condition_array =
  more_than.each_with_object([]) do |(atr, value), sql_array|
    if sql_array.empty?
      sql_array[0] = "#{atr} > ?"
    else
      sql_array[0] << " OR #{atr} > ?"
    end

    sql_array << value
  end
# => ["ios > ? OR android > ?", 13, 14]

sql_condition = Control.sanitize_sql_for_conditions(sql_condition_array)
# => "ios > 13 OR android > 14"

or may be directly

sql_condition = more_than.map { |atr, value| "#{atr} > #{value}" }.join(" OR ")
# => "ios > 13 OR android > 14"

And then

Control.where(company_id: 12345).where(sql_condition)

The query will be like this:

SELECT "controls".* FROM "controls"
WHERE "controls"."company_id" = 12345
AND (ios > 13 OR android > 14);

If that hash will consist of just one element, there will be not OR used like this:

SELECT "controls".* FROM "controls"
WHERE "controls"."company_id" = 12345
AND (ios > 13);
Sign up to request clarification or add additional context in comments.

Comments

0

define a hash instead of an array, hash = { 'android' => 14, 'ios' => 13}

and then form a string that can be passed to where

Complete code looks like this

hash = { 'android' => 14, 'ios' => 13}
str = ''
hash.each do |k, v|
    str += k + ' > ' + v.to_s + ' OR '
end
Control.where(company_id: '12345').where(str[0..-5])

3 Comments

How will this work with one element? What is magic -5?
It will work with any no. Of elements present in the hash. -5 is for ignoring last four characters from str which will be ' OR '
Looks tricky :) There is Array#join method for this
0

A more ActiveRecord approach:

Control.where(company_id: 12345).where("ios > ?", 13).or(Control.where(company_id: 12345).where("android > ?", 14))

Better way:

controls = Control.where(company_id: 12345)
controls = controls.where("ios > ?", 13).or(controls.where("android > ?", 14))

This generates the next SQL query:

SELECT "controls".* FROM "controls" WHERE "controls"."company_id" = 12345 AND (ios > 13 OR android > 14)

1 Comment

How about hash / array as OP wanted?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.