Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Converting an array of objects to ActiveRecord::Relation

I have an array of objects, let's call it an Indicator. I want to run Indicator class methods (those of the def self.subjects variety, scopes, etc) on this array. The only way I know to run class methods on a group of objects is to have them be an ActiveRecord::Relation. So I end up resorting to adding a to_indicators method to Array.

def to_indicators   # TODO: Make this less terrible.   Indicator.where id: self.pluck(:id) end 

At times I chain quite a few of these scopes to filter down the results, within the class methods. So, even though I call a method on an ActiveRecord::Relation, I don't know how to access that object. I can only get to the contents of it through all. But all is an Array. So then I have to convert that array to a ActiveRecord::Relation. For example, this is part of one of the methods:

all.to_indicators.applicable_for_bank(id).each do |indicator|   total += indicator.residual_risk_for(id)   indicator_count += 1 if indicator.completed_by?(id) end 

I guess this condenses down to two questions.

  1. How can I convert an Array of objects to an ActiveRecord::Relation? Preferably without doing a where each time.
  2. When running a def self.subjects type method on an ActiveRecord::Relation, how do I access that ActiveRecord::Relation object itself?

Thanks. If I need to clarify anything, let me know.

like image 587
Nathan Avatar asked Jun 26 '13 22:06

Nathan


People also ask

What is an ActiveRecord relation object?

The Relation Class. Having queries return an ActiveRecord::Relation object allows us to chain queries together and this Relation class is at the heart of the new query syntax. Let's take a look at this class by searching through the ActiveRecord source code for a file called relation.

What is ActiveRecord :: Base in Rails?

ActiveRecord::Base indicates that the ActiveRecord class or module has a static inner class called Base that you're extending.

What is ActiveRecord in Ruby on Rails?

What is ActiveRecord? ActiveRecord is an ORM. It's a layer of Ruby code that runs between your database and your logic code. When you need to make changes to the database, you'll write Ruby code, and then run "migrations" which makes the actual changes to the database.


1 Answers

You can convert an array of objects arr to an ActiveRecord::Relation like this (assuming you know which class the objects are, which you probably do)

MyModel.where(id: arr.map(&:id)) 

You have to use where though, it's a useful tool which you shouldn't be reluctant to use. And now you have a one-liner converting an array to a relation.

map(&:id) will turn your array of objects to an array containing only their id's. And passing an array to a where clause will generate a SQL statement with IN that looks something like:

SELECT .... WHERE `my_models`.id IN (2, 3, 4, 6, .... 

Keep in mind that the ordering of the array will be lost - But since your objective is only to run a class method on the collection of these objects, I assume it won't be a problem.

like image 196
Marco Prins Avatar answered Sep 29 '22 10:09

Marco Prins