Using a left join is going to be your probably most efficient way
The following sql selects only rows where there are no rows with a larger created_at.
See this post for more info: https://stackoverflow.com/a/27802817/5301717
query = <<-SQL
SELECT m.* # get the row that contains the max value
FROM services m # "m" from "max"
LEFT JOIN services b # "b" from "bigger"
ON m.available_id = b.available_id # match "max" row with "bigger" row by `home`
AND m.available_type = b.available_type
AND m.created_at < b.created_at # want "bigger" than "max"
WHERE b.created_at IS NULL # keep only if there is no bigger than max
AND service.available_type = 'User'
SQL
Service.find_by_sql(query)
distinct doesn't take a column name as an argument, only true/false.
distinct is for returning only distinct records and has nothing to do with filtering for a specific value.
if you need a specific available_id
, you need to use where
e.g.
Service.distinct.where(available_type: "User").where(available_id: YOUR_ID_HERE).order(created_at: :desc)
to only get the most recent add limit
Service.distinct.where(available_type: "User").where(available_id: YOUR_ID_HERE).order(created_at: :desc).limit(1)
if you need to get the most recent of each distinct available_id, that will require a loop
first get the distinct polymorphic values by only selecting the columns that need to be distinct with select
:
available_ids = Service.distinct.select(:available_id).where(available_type: 'User')
then get the most recent of each id:
recents = []
available_ids.each do |id|
recents << Service.where(available_id: id).where(available_type: 'User').order(created_at: :desc).limit(1)
end