0

I receive an array of parameters from POST request, they look like the following:

    Parameters: 
     {"search"=>
      { "minor"=>["1", "1"], "major"=>["1", "2"], "proximity_uuid"=>
        ["12345453453", "12345453453"]
      }
    }

which means I am requesting two items:

One with params:

minor: 1

major: 1

prox_uuid: 12345453453

and the second with:

minor: 1

major: 2

prox_uuid: 12345453453

As you may guess, I need to select items from DB that match exact these conditions.

I use the following query:

selectbeacon = Beacon.includes(:ads, :venue).where('minor IN (?) 
and major IN (?) and proximity_uuid IN (?)', params[:search][:minor], 
params[:search][:major], params[:search][:proximity_uuid])

However, the issue is that it selects all records that match at least one condition, but I need to match all three.

As the end result, I am generating complex JSON response.

How should I tweak my query?

thank you in advance,

Roman

2

2 Answers 2

1
set1 = [:minor, :major, :proximity_uuid].map { |i| params[:search][i][0] }
set2 = [:minor, :major, :proximity_uuid].map { |i| params[:search][i][-1] }

query

Beacon.includes(:ads, :venue)
      .where("(minor = ? and major = ? and proximity_uuid = ?) or
              (minor = ? and major = ? and proximity_uuid = ?)",
               *set1, *set2       
             )

After playing sometime in my console, I found another way to write the above query:

Beacon.includes(:ads, :venue)
      .where("(minor, major, proximity_uuid) 
             IN (values(?,?,?),(?,?,?))", *set1, *set2
            )

Tested in console :

Loading development environment (Rails 4.1.1)
[1] pry(main)> Pet.all
  Pet Load (0.7ms)  SELECT "pets".* FROM "pets"
=> [#<Pet id: 6, animals: 1, created_at: "2015-02-21 10:40:19", updated_at: "2015-02-21 10:40:19", name: "Tilly">,
 #<Pet id: 7, animals: 0, created_at: "2015-02-21 10:40:31", updated_at: "2015-02-21 10:40:54", name: "Xav">,
 #<Pet id: 5, animals: 1, created_at: "2015-02-19 18:27:28", updated_at: "2015-02-21 10:41:06", name: "Mua">]
[2] pry(main)> Pet.where("(id, animals) IN (values(?,?),(?,?))",6,1,5,1)
  Pet Load (1.3ms)  SELECT "pets".* FROM "pets"  WHERE ((id, animals) IN (values(6,1),(5,1)))
=> [#<Pet id: 6, animals: 1, created_at: "2015-02-21 10:40:19", updated_at: "2015-02-21 10:40:19", name: "Tilly">,
 #<Pet id: 5, animals: 1, created_at: "2015-02-19 18:27:28", updated_at: "2015-02-21 10:41:06", name: "Mua">]
Sign up to request clarification or add additional context in comments.

4 Comments

thanks Arup! I may receive 1..N sets from POST request. I understand how to map them to corresponding sets, but how should I build query then?
@RomanKrayovskyy Look at my modified code.. and let me know if you didn't understand.
Hey Arup, yeah it looks great! How can I make it work at unknown amount of sets? It can be 1 or 10, I do not know, they are generated dynamically by third party. Any ideas? Somehow process them in the loop?
No. That decision you have to make.. What I wrote is what I can think of. Anything better I don't know.
0

After playing with it for a while and with great help of my friend, here is the solution:

POST parameters should look like the following:

search[0][minor] = 1
search[0][major] = 1
search[0][proximity_uuid] = 1111

...

and query should be:

result = params["search"].inject([]) { | result, (key, item) | result | Beacon.includes(:ads, :venue).where('minor=? and major=? and proximity_uuid=?', item["minor"], item["major"], item["proximity_uuid"]) }

Comments

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.