rails query serializable object - ruby-on-rails

How do I query the database to find objects that contain one or more attributes that are stored as serializable?
For example, I have a concert which occurs only in certain cities. I want to make a Concert object with a column called cities and store an array of cities.
If I want to query my database to find all concerts that occur in 1 city (or all concerts that occur in an array of n cities), how do I do this?

The best way to do this isn't to store it in a serialized column, but a separate table called Cities. Then you can do this:
City.find_by_name('Cityname').concerts

One possible way to query would be to use SQL's LIKE condition. This would work for boolean conditions in serialized tables.
For example to find those Users with the 'notification' option on,
users=User.arel_table
User.where(users[:options].matches("%notification: true%"))
As for other type of variables this would not be as feasible.

Related

Is it possible to get column names from an relation even if result rows are zero?

In Rails, one uses ActiveRecord for querying the database. ActiveRecord's query results in an ActiveRecord::Relation object. Since we can execute ActiveRecord::Relation#select and specify arbitrary SQL select clause, sometimes the records returned by the database contains columns which does not exist in the database.
If this relation contains more than one row, then one can get the column names of the relation by using the_relation.first.attributes. When no records were returned by the query, however, this method is not possible.
Question
Is there any way to get the Query's resulting column names of an ActiveRecord::Relation even if no rows were returned?
The motivation
For example, when you're building an Daru::DataFrame instance or some other Relational Data, you'd want to obtain the attribute names even if there is no records in the result.
Yes you can get the column names
If the result is ActiveRecord::Relation then you can use something like this
the_relation.column_names

Rails - Get records of a specific id and store it in an Array

How do I get records from a table with a specific ID and store these records in an Array?
For better understanding I try to explain it to you more clear:
Imagine a table with the following columns: (ID,FIX_ID,AMOUNT)
where ID is an unique ID which always will auto_incremented by 1.
FIX_ID is an ID which can appear multiple times in the table.
And AMOUNT is just a simple type which represents the amount of some "things".
So all I want to get now is every record from the table which have the FIX_ID that I am looking for.
Remember: The FIX_ID is not unique => it can appear multiple times.
And that's it. So imagine that I want to get all records with the FIX_ID of 10. All these records which I will get should be stored in an Array.
My question to you: Is it possible to realize this "request" to the database with ActiveRecord?
If so, then how?
You can get an ActiveRecord::Relation object like this:
ModelName.where('FIX_ID = ?', 10)
Relation object will perform a database query as soon as you call methods like all, each or any? on it. If you really need an array, call to_a on that Relation:
ModelName.where('FIX_ID = ?', 10).to_a

Model.find_by_sql vs connection.query, which one is better?

In rails-
I need to execute a sql query against the database; the query is not related to any specific Model it can have mix data from multiple tables or from some other table. I have ways to do this=-
first is by executing query agains Model and capture the result like this-
res=User.find_by_sql("select * from customers joins and conditions")
res=User.find_by_sql("select * from [other table] joins and conditions")
Problem with this approach, I am not feeling comfortable with it because in User class objects I am capturing data of other table. like the first query result has data from customer table so in the user object I got customer's attribute. And more interesting problem is- if the resulting query has id attribute then
res.first.id will be id of customer and
if User model has relation with UserRoles model and if I access this relation with res.first.roles then it will fetch roles from UserRole for customer id, which is completely wrong.
And there might be may problems also.
So I think it has lot of chaos.
And good part is we dont not need to deal with connection and result would be an array of objects. so accessing object attributes with res.first.id is easier the hast like row["id"].
and second approach to use ActiveRecord connection and execute the query like
this res = ActiveRecord::Base.connection.query("sql query")
in place of query we can use select_one, select_all and can also make query parameterized.
The problem it has is it returns array of hash, but I need array of objects for easy accessibility in code. So I wrote a class to convert hash to object (I think rail does same thing in background) and is working fine.
So I need some suggestion on both the approach and need to decide which one is better.
First find_by_sql vs select_all
find_by_sql, This method returns an array of objects by initiating them.
users = User.find_by_sql("SELECT * FROM users"); #=> [#, #, #, # ....]
Accessing properties
users[0].name #Getting property in object oriented fashion
select_all, This method returns an array of objects but does not initiate them, and each object represents a row of database.
users = User.connection.select_all("SELECT * FROM users"); #=> #
Accessing properties
users[0]["name"] #Getting property in non-object oriented fashion
Whether find_by_sql is better, because of it is a simple way of custom querying to the database and returns instantiated objects

Rails 4 order by virtual attribute

I have a Product model which has name and description columns in the database.
I also have a Product.search_results_for(query), where query is a string like "Green Apple".
I need to return an ActiveRecord::Relation of the results ordered by which is the best hit. Currently, I'm setting a search_result_value to each product. search_result_value IS NOT a column in the database, and I don't want it to be.
So in essence, I have an ActiveRecord::Relation of Products that I need to order by search_result_value without changing it to an array, which is an instance variable that isn't stored in the database. How can I do this?
Something like this:
Product.order(:search_result_value)
If you do not put the value in a column or express the logic in search_result_value in pure SQL, then you’ll have to load all Products into memory and then sort them in Ruby using sort_by:
Product.all.to_a.sort_by(&:search_result_value)

What are Indexes in the Xcode Core-Data data model inspector

In Xcode you can add "Indexes" for an entity in the data model inspector.
For the screenshot I did hit "add" twice so "comma,separated,properties" is just the default value.
What exactly are those indexes?
Do they have anything to do with indexed attributes? And if they have what is the difference between specifying the Indexes in this inspector and selecting "Indexed" for the individual attribute?
Optimizing Core Data searches and sorts
As the title says, indexing is to speed up searching and sorting your database. However it slows down saving changes to persistant store. It matters when you are using NSPredicate and NSSortDescriptor objects within your query.
Let's say you have two entities: PBOUser and PBOLocation (many to many). You can see its properties at the image below:
Suppose that in database there is 10,000 users, and 50,000 locations. Now we need to find every user with email starting on a. If we provide such query without indexing, Core Data must check every record (basically 10,000).
But what if it is indexed (in other words sorted by email descending)? --> Then Core Data checks only those records started with a. If Core Data reaches b then it will stop searching because it is obvious that there are no more records whose email starts with a since it is indexed.
How to enable indexing on a Core Data model from within Xcode:
or:
Hopefully they are equivalent:-)
But what if you wanted: Emails started with a and name starts with b You can do this checking INDEXED for name property for PBOUser entity, or:
This is how you can optimise your database:-)
Use the Indexes list to add compound indexes to the entity. A compound index is an index that spans multiple attributes or relationships. A compound index can make searching faster. The names of attributes and relationships in your data model are the most common indexes. You must use the SQLite store to use compound indexes.
Adding a row with a single attribute to the Indexes list is equivalent to selecting Indexed for that attribute: It creates an index for the attribute to speed up searches in query statements.
The Indexes list is meant for compound indexes. Compound indexes are useful when you know that you will be searching for values of these attributes combined in the WHERE clause of a query:
SELECT * FROM customer WHERE surname = "Doe" AND firstname = "Joe";
This statement could make use of a compound index surname, firstname. That index would also be useful if you just search for surname, but not if you only search for firstname. Think of the index as if it were a phone book: It is sorted by surname first, then by first name. So the order of attributes is important.

Resources