pratski
pratski

Reputation: 1488

How to pull the newest object from an array without using first or last?

I want to pull out the newest post from an array of posts. But using .first is messing it up for some reason. For some it is pulling the newest, while for some it is pulling the oldest.

I have: default_scope order: posts.created_at DESC

so first should give me the latest post but sometimes it doesn't. Is there a better way to get the newest post?

Update

Here is my controller code:

@users = User.includes(:ideas).order('users.updated_at DESC')

I want to order users by last updated DESC and then for each user show his most recent post. I think the default_scope order: posts.created_at DESC is clashing with .order('users.updated_at DESC')

In my view I am doing:

@users.each do |user| post = user.posts.first end

It's not working right. HOw do I fix this without N+1 problem?

Upvotes: 0

Views: 85

Answers (4)

Damien
Damien

Reputation: 27473

For some reason, the order clause in the default scope is being overwritten.

You can force the ordering with reorder:

Post.reorder(created_at: :desc).first

Use it in a named scope:

class Post < ActiveRecord::Base
  scope :latest, -> { reorder(created_at: :desc).first }
end

References: reorder on Rails API

Edit for the updated question

With the default scope defined as below in post.rb:

default_scope { order(created_at: :desc) }

You can simply write:

@posts = Post.includes(:user).group('posts.user_id')

You will get the latest posts (one per user)

If some posts don't have a user:

@posts = Post.joins(:user).select('posts.*, users.username AS user_username, etc........').group('posts.user_id')

Each post of @posts will get a user_username method without the n+1 problem. You can of course define more custom methods depending of what you need.

Upvotes: 1

Rails Guy
Rails Guy

Reputation: 3866

It should be like :

Post.order('created_at DESC').first

Upvotes: 0

Voldy
Voldy

Reputation: 12868

You can sort by id if it's incremental:

scope :latest, -> { order('id DESC') }
Post.latest.first 
Post.latest.limit(10)

One more benefit for relational databases here is that there is an index on id already.

Upvotes: 1

Miotsu
Miotsu

Reputation: 1776

If

 Post.first(:order => 'created_at DESC')

won't work (or are you interested in the most recently updated) there's something broken somewhere...

Upvotes: 0

Related Questions