Guidelines for Obtaining a List of Identifiers from an ActiveRecord Model

I have an ActiveRecord Language model, with id and short_code (there are other columns, but they are not relevant to this issue). I want to create a method that will be provided with a list of shortcodes and return a list of identifiers. I do not need associations, I just need to finish the array, which looks like [1, 2, 3, ...].

My first thought was to do something like

 def get_ids_from_short_codes(*short_codes) Language.find_all_by_short_code(short_codes.flatten, :select => 'id').map(&:id) end 

but I'm not sure if it wastes time / memory / processing.

My question is twofold:

  • Is there a way to trigger ActiveRecord discovery that simply returns an array of a specific column of the table, rather than instantiating objects?
  • If so, is it really worth collecting an array of length n rather than creating instances of n ActiveRecord objects?

Note that for my specific purpose, n will be approximately 200.

+4
source share
6 answers

Honestly, for 200 entries, I would not worry about that. When you get to 2000, 20 000 or 200 000 records - then you can worry about optimization.

Make sure the short_code index is indexed in your table.

If you are still concerned about performance, look at development.log and see what database numbers are for this particular call. You can customize the query and see how it affects performance in the log. This should give you a rough estimate of performance.

+6
source

In Rails 3.x, you can use the pluck method, which returns the values ​​from the requested field without creating objects to store them.

This will give you an array of identifiers:

 Language.where(short_code: short_codes.flatten).pluck(:id) 

I should mention that in Rails 3.x you can only cut one column at a time, but in Rails 4 you can pass multiple columns to rip.

By the way, here is a similar answer to a similar question

+6
source

Agree with the previous answer, but if you absolutely must, you can try this

 sql = Language.send(:construct_finder_sql, :select => 'id', :conditions => ["short_code in (?)", short_codes]) Language.connection.select_values(sql) 

A little ugly, but it does not create objects in memory.

+5
source

If you use associations, you can get the original identifiers directly from ActiveRecord. eg:.

 class User < ActiveRecord::Base has_many :users end irb:=> User.find(:first).user_ids irb:>> [1,2,3,4,5] 
+5
source

Phil is right, but if you find that this is a problem. You can send a raw SQL query to the database and operate at a lower level than ActiveRecord. This may be useful for such situations.

 ActiveRecord::Base.connection.execute("SQL CODE!") 

Before resorting to this, mark your code first.

+3
source

It really is a matter of choice.

Overkill or not, ActiveRecord is supposed to provide you with objects since this is ORM. And, as Ben said, if you don't want objects, use raw SQL.

0
source

Source: https://habr.com/ru/post/1286473/


All Articles