5

Knowing that by default Rails orders data by ID, how can I order by ids given to the where clause?

ids = Bookmark.where(user_id: 7).order(created_at: :desc).pluck(:company_id)

Result:

[146, 140, 128, 4, 2]

Now, when I try to get the companies in the same order from ids

Company.where(id: ids).pluck(:id)

Result:

[2, 4, 128, 140, 146]

Expected Result:

[146, 140, 128, 4, 2]

My pretended result will be the same in both cases (same order). The companies should be returned in the same order that the Bookmarks on that company where created.

Paulo Fidalgo
  • 21,709
  • 7
  • 99
  • 115

6 Answers6

3
Company.includes(:bookmarks) .where(id: ids).order('bookmarks.created_at desc').pluck(:id)
Oleh Sobchuk
  • 3,612
  • 2
  • 25
  • 41
1

So it looks like given a user ID, you want a list of companies sorted by the created_at date of the bookmarks that join Users and Companies.

Am I correct in assuming that Users and Companies share a many-to-many relationship through Bookmarks?

If that's the case, the following "join" could work for you!

Company.joins(:bookmarks).where('bookmarks.user_id = ?', 7).order('bookmarks.created_at')

Of course, in your code, this could be generalized to grab companies for any user!

user_id = 42
companies = Company.joins(:bookmarks).where('bookmarks.user_id = ?', user_id).order('bookmarks.created_at')

ActiveRecord "joins" reference

  • https://stackoverflow.com/questions/56669484/how-to-get-value-using-join-table-with-different-values/56680298#56680298 – Anshul Riyal Jun 20 '19 at 08:46
0

You are explicitly ordering by created_at in order(created_at: :desc)

You want to order by company_id ids = Bookmark.where(user_id: 7).order(:company_id).pluck(:company_id)

Ray Baxter
  • 3,181
  • 23
  • 27
  • I believe this will sort by the `id` on `bookmarks`, not the `pluck`ed `company_id`. – Jack Collins Jan 20 '16 at 20:03
  • @RayBaxter I have updated the question to clarify the order I want in companies. – Paulo Fidalgo Jan 20 '16 at 21:50
  • @RayBaxter The order(created_at: :desc) is on Bookmarks, but I want the companies from the same order that the Bookmarks had been created. – Paulo Fidalgo Jan 20 '16 at 22:17
  • @PauloFidalgo If that is the case, then you almost had the correct query in the first place. `ids = Bookmark.where(user_id: 7).order(:created_at).pluck(:company_id)` – Ray Baxter Jan 20 '16 at 22:22
0

What exactly are you trying to order by... the company_id?

pluck returns an array, which is why this does NOT work:

ids = Bookmark.where(user_id: 7).pluck(:company_id).order(company_id: :desc)
## undefined method `order' for Array

Instead, you can call sort on the array.

ids = Bookmark.where(user_id: 7).pluck(:company_id).sort

That should do the trick

Jack Collins
  • 1,145
  • 10
  • 21
0

Probably you can try this:

company_by_id = Company.find(ids).index_by(&:id) # Gives you a hash indexed by ID
ids.collect {|id| company_by_id[id].id }
Yang
  • 1,915
  • 1
  • 9
  • 15
0

This is how I have solved the question:

Bookmark.includes(:company).where(user_id: current_user).order(created_at: :desc)

and when iterating over the elements I use:

record.company instead of record.

This way I have the companies from the same order that the Bookmarks where created.

Paulo Fidalgo
  • 21,709
  • 7
  • 99
  • 115
  • 1
    I encountered this problem before. I ended up using Gunchars answer from [here](http://stackoverflow.com/questions/1680627/activerecord-findarray-of-ids-preserving-order). I think that is faster than iterating the bookmark records in this answer of yours. Hope it helps. – Jay-Ar Polidario Jan 20 '16 at 22:35
  • @Jay-ArPolidario I need to iterate in the view. But thanks for pointing it. – Paulo Fidalgo Jan 21 '16 at 11:04