52772

Hash/Array to Active Record

Question:

I have been searching everywhere but I can't seem to find this problem anywhere. In Rails 5.0.0.beta3 I need to sort a my @record = user.records with an association and it's record. The sort goes something like this.

@record = @record.sort_by { |rec| If user.fav_record.find(rec.id) User.fav_record(rec.id).created_at Else rec.created_at End

This is just an example of what I do. But everything sorts fine.

<strong>The problem:</strong> This returns an array and not an Active Record Class.

I've tried everything to get this to return an Active Record Class. I've pushed the sorted elements into an ID array and tried to extract it them in that order, I've tried mapping. Every result that I get turns my previous active record into an array or hash. Now I need it to go back into an active record. Does anyone know how to convert an array or hash of that active record back into an Active Record class?

Answer1:

There isn't a similarly easy way to convert ActiveRecord to array.

If you want to optimize the performance of your app, you should try to avoid converting arrays to ActiveRecord queries. Try and keep the object as a query as long as possible.

That being said, working with arrays is generally easier than queries, and it can feel like a hassle to convert a lot of array operations to ActiveRecord query (SQL) code.

It'd be better to write the sort code using <a href="http://guides.rubyonrails.org/active_record_querying.html" rel="nofollow">ActiveRecord::Query methods</a> or even writing it in plain SQL using find_by_sql.

I don't know what code you should specifically use here, but I do see that your code could be refactored to be clearer. First of all, If and Else should not be capitalized, but I'm assuming that this is just pseudocode and you already realize this. Second, your variable names should be pluralized if they are queries or arrays (i.e. @record.sort_by should be @records.sort_by instead).

It's worth mentioning that ActiveRecord queries are difficult to master and a lot of people just use array operations instead since they're easier to write. If "premature optimization is the root of all evil", it's really not the end of the world if you sacrifice a bit of performance and just keep your array implementation if you're just trying to make an initial prototype. Just make sure that you're not making "n+1" SQL calls, i.e. <em>do not</em> make a database call every iteration of your loop.

Here's an example of an array implementation which avoids the N+1 SQL issue:

# first load all the user's favorites into memory user_fav_records = user.fav_records.select(:id, :created_at) @records = @records.sort_by do |record| matching_rec = user.fav_records.find { |x| x.id.eql?(rec.id) } # This is using Array#find, not the ActiveRecord method if matching_rec matching_rec.created_at else rec.created_at end end

The main difference between this implementation and the code in your question is that I'm avoiding calling ActiveRecord's find each iteration of the loop. SQL read/writes are computationally expensive, and you want your code to make as little of them as possible.

Recommend

  • Does using package generics require the package to be in Depends or Imports?
  • How to Optimize mach_msg_trap
  • if clause in bigquery
  • Obtain access token for both Microsoft Graph and individual service API endpoints (Outlook REST APIs
  • How to make a div appear under button
  • What to use (best/good practice) for the secret key in HMAC solution?
  • How to search for a record and then delete it
  • Is it possible to collect a stream to two different collections using one line?
  • QObject::findChild() returns None without obvious reason
  • Rails CarrierWave versions are not created for some reason
  • Can I put a + sign in a folder with IIS?
  • bcrypt-nodejs compare method returns false every time
  • ruby/rails: extending or including other modules
  • Gforce min not supported for character in data.table
  • Mongodb update() vs. findAndModify() performace
  • Doctrine2 inverse persistance not working in nested forms
  • Does the MySQL IN clause execute the subquery multiple times?
  • It is possible use the same sql azure instance from two different cloud service of two different sub
  • Action Pack components in Rails
  • Convert SQLite database to XML
  • Android changing fragment order inside FragmentPagerAdapter
  • accepts_nested_attributes_for practical form use for in Rails 3
  • Implicit joins and Where in Doctrine - how?
  • Jquery popup on mouse over of calendar control
  • Scala multiline string placeholder
  • WPF Visiblity Binding to Boolean Expression with multiple Variables
  • Conversion from string “a” to type 'Boolean' is not valid
  • How do I get HTML corresponding to current DOM tree?
  • Rails Find when some params will be blank
  • Row Count Is Returning the incorrect number using RaptureXML
  • How to create a file in java without a extension
  • How to delay loading a property with linq to sql external mapping?
  • Jenkins: How To Build multiple projects from a TFS repository?
  • Is my CUDA kernel really runs on device or is being mistekenly executed by host in emulation?
  • Arrays break string types in Julia
  • Trying to get generic when generic is not available
  • Java static initializers and reflection
  • unknown Exception android
  • Observable and ngFor in Angular 2
  • Unable to use reactive element in my shiny app