Reputation: 2290
How can I run a raw sql query and get an ActiveRecord_Relation
instance returned?
On a sqlite3 db and Rails 4.2, ActiveRecords::Base.exec_query(sql)
returns an ActiveRecord_Result
instance. ActiveRecords::Base.execute(sql)
returns an array. This is troublesome because I cannot run subsequent "ActiveRecord queries" or raw sql queries on the returned objects.
More generally, I would like to know how to chain "complex" sql queries in Rails. By complex I mean I could not figure out a way to do it through the "ORM methods" given by ActiveRecords. And by chaining I mean I would like to break it down in several SQL queries, for performance reasons. Example: I just want to run the big heavy first SQL query once, store the result and then run lighter sql queries depending on the user behavior.
I am currently trying to optimize a database visualization through dataTables implemented with server-side-processing. The server has to run an unnecessarily complex SQL query every time the user interacts with the table because I could not break it down in simpler queries. I looked at the following questions but could not figure out a satisfying solution:
Convert Array#select to active record query in rails 4
Upvotes: 19
Views: 4996
Reputation: 1178
This is a way to get an ActiveRecord_Relation from raw_sql.
It works best if you actually have a model matching the fields you're trying to retrieve, but as you can see with test_attribute, any data will be loaded.
# Just an example query, any query should be ok
query = <<-SQL
SELECT *, TRUE AS test_attribute
FROM users
WHERE sign_in_count < 10
SQL
relation = User.select('*').from("(#{query}) AS users")
relation.class
# User::ActiveRecord_Relation
relation.first.test_attribute
# true
Upvotes: 26