postgresql and RoR - how quering a json type field where value is in an array - ruby-on-rails

Say I have a User class with a json type address field that has keys for city and country like this: adress: {city: 'NY', country: 'USA'} and I want to get all the users that live in an array of country names like: country_names = ['Iran', 'Iraq', 'Yemen'].
How do can I do it in Ruby on Rails?
I've tried:
User.where("address->>'country' IN ?", country_names)
but I get a syntax error. what is the correct way?

The list of values of the IN clause should be enclosed by parentheses:
User.where("address->>'country' IN (?)", country_names)

Related

Hstore Query to find records matching with any array element using ruby on rails

I've a hstore field in a database table. I want to write a Query to find records matching with any array element in any hash of hstore field using ruby on rails.
Users Table
--------------------------------------------------------------------------------
ID Name sectors(hstore)
1 Piotr {"aviation"=>"0", "oil_and_gas" => "50", "transport" => "50"}
2 reza {"oil_and_gas" => "70", "energy" => "30"}
3 pat {"transport" => "40", "energy" => "60"}
4 Kim {"infrastructure" => "20", "healthcare" => "20", "industrial" => "60"}
considering above test data, I want to write a query on hstore field to get all records having any key like ['oil_and_gas', 'energy', 'transport']
I can match and find single sector records as its mentioned in https://nandovieira.com/using-postgresql-and-hstore-with-rails, but my requirement is to find any record where hstore hash is having any one key matching with any one element of array.
I'm using Rails 5.1.6.2, ruby 2.5.3
May be you are looking for the following operator:
hstore ? key # does hstore contain key?
Query may looks like so:
User.where("sectors ? 'oil_and_gas'")
.or("sectors ? 'energy'")
.or("sectors ? 'transport'")
According to postgresql docs
Check for a specific key in hstore column You can check for a specific
key in an hstore column using the ? operator in the WHERE clause. For
example, the following statement returns all rows with attr contains
key publisher.
SELECT
title,
attr->'publisher' as publisher,
attr
FROM
books
WHERE
attr ? 'publisher';

RedBean php count query with where

I need a count query in redbean php with where condision
I used
R::count("company","country like 'United States'");
where country name is the where condision
plz suggest some thing
Redbean expects an array on 3rd parameter, so you should use:
R::count("company", "country like ?", ["United States"]);
note that every ? should match one element in array, but if you have more conditions for the same value, you can also use :param once instead, for ex:
R::count("company", "country like :name OR city like :name", [":name" => "United States"]);
R::count("company","country like 'United States'");
this works fine.........
but this doesn't
R::count("company","country like '".$country."'");

Rails JSON query combined with other data types

I have a Contact model with a string and json attribute
the string attribute stores the phone_number and the json attribute stores some other data.
I want to run a query like this
Contact.exists?(phone_number: '+255788778899', data: {name: 'Gamma',
region: 'The Great one'})
I have searched all over google and SO, but most of the articles simple give a way of find the record with a json string only and which has only one key
e.g
Contact.exists?("data ->> 'name' = 'Gamma'")
However my intention is to find if a contact exists with the phone number and the full json attribute specified in the same query
How can I do this?
One way to accomplish it is to use where and present? instead of exists?. For example:
Contact.where("data ->> 'name' = 'Gamma' AND phone_number = '+255788778899'").present?
The other benefit of this approach is if you're going to use the collection/object if it does exist, then you can first run the query:
#contacts = Contact.where("data ->> 'name' = 'Gamma' AND phone_number = '+255788778899'")
And then later, checking for its presence won't hit the database again:
#contacts.present?
UPDATE
If you need to use variables within your query, you can do so, but be sure to wrap them in quotes. For example:
name = 'Gamma'
phone = '+255788778899'
Contact.where("data ->> 'name' = '#{name}' AND phone_number = '#{phone}'")
How about chaining it with a where clause like this:
Contact.where(phone_number: '+255788778899').exists?("data ->> 'name' = 'Gamma'")

How do I create a scope to find all objects in my class that `include?` a string on an attribute?

I have a Node object that has an attribute called cached_user_tag_list, that stores a comma separated list of email addresses as a string like this:
[3] pry(main)> n.cached_user_tag_list
=> "gerry#test.com, danny#test.com"
If I set a local variable to be one of those email addresses, I can use ruby's include? string method to find if a node contains that email address. Here is an illustration:
[6] pry(main)> g = "gerry#test.com"
=> "gerry#test.com"
[8] pry(main)> n.cached_user_tag_list.include? g
=> true
What I would like to do, is create a Scope on my Node class/model that will accept g and search against the column/attribute cached_user_tag_list for all the Nodes in my DB and return a collection or AR Relation of all of those Nodes that contain that email address stored in the variable g within their string at cached_user_tag_list.
How do I do this?
Edit 1
I tried Node.where('cached_user_tag_list.include?'(g)), but that didn't work.
If it's just plain old string column with comma separated values, you can do something like this:
scope :find_nodes_which_include, ->(email) { |email| where("cache_user_tag_list like ?", "%#{email}%") }

Model has a field which is an array of strings, how can I find all records that contain a certain string in the array?

My model has a field called user_ids, which is an array of strings. How can I find all of the records which include a certain string, string_1, in user_ids?
I'm using Rails 3.0.1 & Ruby 1.9.2p0.
You can use something like this scope:
scope :some_scope_name, lambda {|user_id| where(["user_ids RLIKE ?", user_id])}
I used this type of scope in project, where I have to find all records with list_ids column match some criteria.
.. or you can use find_by_sql method with same SQL: ["user_ids RLIKE ?", criteria]

Resources