ActiveRecord: search by array field element inside another array - ruby-on-rails

I have an object with an array field, called emails
user.emails = ['a#b.c','d#e.f']
I want to find all the users from a list of emails:
emails_to_find = ['a#b.c','x#y.z']
I tried running
User.where(emails: emails_to_find)
but I get
ActiveRecord::StatementInvalid: PG::InvalidTextRepresentation: ERROR: array value must start with "{" or dimension information
How do I do that? What the error means?

If the column is of type Array and in the migration that created it you have something like t.string 'emails', array: true, try using:
User.where("emails #> ARRAY[?]::varchar[]", ['a#b.c','d#e.f'])
User.where("'a#b.c' = ANY (emails)")

Related

postgresql will not save array of empty arrays

A user model has a goal field that is an array:
t.integer "goal", default: [], array: true
A valid entry for goal is [[],[],[]]. If I do
Match.create(goal: [[],[],[]])
I get an exception:
ActiveRecord::StatementInvalid: PG::InvalidTextRepresentation: ERROR: malformed array literal: "{{},{},{}}"
DETAIL: Unexpected "}" character.
I know that I can work around this by saving it as goal: [], but I lose information about the number of sub-arrays. Is there a way to fix this?
You’ve gone from trying to store an array of numbers to an array of fixed length which includes null values or even sub arrays. Therefore, a t.integer field is no good. You need to use a t.jsonb or t.json field.
See the Postgres docs on JSON datatypes

Mongoid order by length of array

How to sort the Mongoid model by the length of the array which is a field inside the model.
Mongo documentation says:
You cannot use $size to find a range of sizes (for example: arrays
with more than 1 element). If you need to query for a range, create an
extra size field that you increment when you add elements. Indexes
cannot be used for the $size portion of a query, although if other
query expressions are included indexes may be used to search for
matches on that portion of the query expression.
So we cannot order by using mongo's $size.
You can solve your task by adding new field, which will store array size.
class Post
include Mongoid::Document
field :likes, type: Array, default: []
field :likes_size, type: Integer
before_save do
self.likes_size = likes.size
end
end
Sort posts by likes_size:
Post.order_by(likes_size: :desc)
Document says that you can't orderby using size.
Try adding a new column containing the value of size and sort it which will work as order by.
In ruby, you can sort an array like this :
my_array.sort_by(&:my_attr)
It will sort the array my_array by the attribute my_attr of each element inside the array.
You can also write it like this :
my_array.sort_by{|element| element.my_attr }
Which is exactly the same, it will sort by the my_attr attribute of each element. This second syntax is for when you want a more complex sort condition than just the result of a method of each element.
Documentation : http://ruby-doc.org/core-2.3.1/Enumerable.html#method-i-sort_by

Ruby Rails, JSON - match results if key exists

The set up is ruby on rails, in a postgres database. The table is called line_sources and a JSON column is called names. I want to return all rows where the names column contains a key called away_names. I'm trying this but they fail:
LineSource.where("names -> 'away_names'")
and
LineSource.where("names ->> 'away_names' = '%'")
Try this :
where("(names->'away_names') is not null")
You can use #> to get the JSON object at that path.
where("(names #>'{away_names}') is not null")
Basic key operators to query the JSON objects :
#> : Get the JSON object at that path
->> : Get the JSON object at that path as text
{obj, n} : Get the nth item in that object

A select in rails query does not return an array

Here is the rails 3 query in the app:
Order.where('id IN (?)',ContractItem.where(contract_id: #contract.id).select('contract_item_id'))
Here is the only record in contract_item table:
As shown in the record, the #contract.id is equal to 1 and we expect ContractItem.where(contract_id: #contract.id).select('contract_item_id') returns array [2].
So Order.where('id IN (?)',ContractItem.where(contract_id: #contract.id).select('contract_item_id'))should return order#2. However what we have got is nothing. We figure an empty array must be returned instead. Is there something wrong with the code above?
You're getting back an array, but it's an array of ContractItem objects with a single column, not an array of numbers.
Try instead...
Order.where('id IN (?)',ContractItem.where(contract_id: #contract.id).pluck(:contract_item_id))

getting meta data from resultset object in rails

I am using some custom queries in rails.
code snippet looks like
#time_spent = TimeEntry.find(:all,
:joins => "INNER JOIN sometable ON x = y",
:select =>"id, subject, spent_on")
now to get values I am using
#time_spent[index][:spent_on]
#time_spent[index][:subject]
what I want is to use index numbers in place of symbols. So that at run time I don't need to know the fields in the select clause.
for e.g. i want to do some thing similar to this
#time_spent[index][1]
#time_spent[index][2]
or
If I could get metadata of resultset i can use that information
Comments please?
When #time_spent is a collection of objects, this will get the attribute's value for the index specified for the first [0] item in that collection:
#time_spent[0].attributes.values[index]
So, for example, to get the 5th attribute's value for the 2nd object in the collection:
#time_spent[1].attributes.values[4]
to get field names from result set, use attributes.keys method

Resources