0

An array of IDs are being collected

@valid_ts = []
@valid_ts = @valid_ts << dst_1.id 
@valid_ts = @valid_ts << dst_2.id

note : each row shown above is in fact run for each member of a collection (i.e. dst_1.size > 1)
When comes time to query the database

slots = Timeslot.where('id IN (?)', @valid_ts).all

the goal is to generate the collection in the order that these members were added to the collection. Rails defaults to updated_at, otherwise the query has to invoke one of the class's attributes, none of which are useful for the targetted context.

How can the originating order of the array be respected with Rails?

Jerome
  • 5,583
  • 3
  • 33
  • 76

1 Answers1

1

If you are using Mysql you can use field function.

Timeslot.where(id: @valid_ts).order("field(id, #{ids.join ','})")

If you are using Postgres you can use position function. -

Timeslot.where(id: @valid_ts).order("position(id::text in '#{ids.join(',')}')")

But ActiveRecord can perform for both if you are using rails >= 5.2.0 as it is added from that version. Most likely it is also backported in rails 5.0. The pull request and the commit and the documentation.

Timeslot.find(@valid_ts)

Check this SO post for more ideas.

Rafayet Monon
  • 1,019
  • 8
  • 16
  • `Timeslot.find(@valid_ts)` will not work, as Rails has no idea of the ordering criteria and defaults to updated_at attribute. Your link does provide a good direction for AR query. I have thus re-cast the question https://stackoverflow.com/questions/60912122/activerecord-condition-with-order-based-on-ad-hoc-order-of-attributes , as there is peculiarity. Will delete this one subsequently given it may be too miseleading. – Jerome Mar 29 '20 at 09:11
  • Did you try it? I tried it myself in one of my Table. It returned as I provided the array. It's in the rails commits. pull request - https://github.com/rails/rails/pull/22653 the commit - https://github.com/rails/rails/commit/2c5acb20dd944cc061a03e8d1ca6d3e469c0d46e – Rafayet Monon Mar 29 '20 at 10:02
  • Edited the answer with links as which that The `find` returned records are in the same order as the ids you provide. If you want the results to be sorted by database, you can use ActiveRecord::QueryMethods#where(taken from the docs). – Rafayet Monon Mar 29 '20 at 10:14
  • The rails 5.2 syntax is correct, however for rails 4, the syntax for Postgre searching is failing with error `undefined local variable or method 'ids'` – Jerome Apr 21 '20 at 06:32