Mark Hustad
Mark Hustad

Reputation: 169

Rendering most recent articles rails 4

Its currently listing my oldest articles at the top and I want to do the opposite. I think I need to order it as created_at somewhere but I have yet to make it work. I know this is easy but I'm still a newbie. Thanks

Currently I have

<div class="bit-75">
<h2 id="title"><%= link_to article.title, article_path(article) %></h2>
<br>

<ul id="article-links">
  <div id="article-image"><%= image_tag article.image_url %></div>
  <br>
  <li id="article-text"><%= article.text %></li>
<br>
<%= article.created_at %>
<br>

<% if admin_signed_in? %>
  <li><%= link_to 'Edit',           edit_article_path(article) %></li>
  <li><%= link_to 'Destroy',        article_path(article),
                method: :delete, data: { confirm: 'Are you sure?'} %></li>
  <li><%= link_to 'New article', new_article_path %></li>
<% else %>                
  <li><%= link_to 'Make a Comment', article_path(article) %></li>              
</ul>
<% end %>   

article.rb

   class Article < ActiveRecord::Base
   has_many :comments, dependent: :destroy
   validates :title, presence: true,
                length: { minimum: 5 }
   mount_uploader :image, ImageUploader                  
   end

articles controller

def new
 @article = Article.new
end

def index
 @article = Article.all
end

def create  
 @article = Article.new(article_params)

  if @article.save
  redirect_to @article
else
  render 'new'
 end
end

def edit
  @article = Article.find(params[:id])
end

def update
 @article = Article.find(params[:id])

 if @article.update(article_params)
   redirect_to @article
 else
   render 'edit'
 end
end


def show
  @article = Article.find(params[:id])
end

def destroy
  @article = Article.find(params[:id])
@article.destroy

 redirect_to articles_path
end

Upvotes: 0

Views: 76

Answers (2)

Justin
Justin

Reputation: 4940

In your Article model, article.rb, you can set a default_scope like this:

default_scope -> { order('created_at DESC') }

However, this method will sort the articles like this on all pages. If you only want to sort them like this on one action, say your def index, then something like this might work better.

@articles = Article.order('created_at DESC')

Like @ShamsulHaque said in his comment.

Here is a good read about default scopes.

Update

If you prefer to use scopes, like @rich says, then the syntax would look like this:

scope :recent, ->(order = 'desc') { order(created_at: order.to_sym) }

Which you would have the option, in your controller, to call either asc or desc like so:

@articles = Article.recent('asc')
@articles = Article.recent('desc') # although we defaulted to 'desc', so really only need Article.recent

To explain a bit, @rich included the to_sym to convert the string 'desc' or 'asc' to a symbol like :desc or :asc. If you did not do this, you would get an error like

Direction should be :asc or :desc

Hope this helps.

Upvotes: 2

Richard Peck
Richard Peck

Reputation: 76784

Scopes

Using default_scope is a little taboo (can cause problems) - you'll be much better using a standard scope with a condition:

#app/models/article.rb
Class Article < ActiveRecord::Base
   scope :recent, (order = "desc") -> { where created_at: order.to_sym}
end

This will allow you to call:

@article = Article.recent("asc")

A nice extension to @justin's answer ;)

Upvotes: 1

Related Questions