Reputation: 924
Controller:
class PostsController < ApplicationController
def index
@posts = Post.published
respond_to do |format|
format.html # index.html.erb
format.json { render json: @posts }
end
end
def show
.
.
end
def month
@posts_by_month = Post.find(:all, :order => "created_at DESC").group_by { |post| post.created_at.strftime("%B %Y") }
respond_to do |format|
format.html # index.html.erb
format.json { render json: @posts }
end
end
end
posts#month View:
<% @posts_by_month.each do |monthname, posts| %>
<p><%= monthname %></p>
<div>
<ul>
<% posts.each do |post| %>
<li><p><%= post.title %></p></li>
<% end %>
</ul>
</div>
<% end %>
posts#index view:
<h1>Listing posts</h1>
<%= render :partial => @posts %>
<h2>Blog archive</h2>
<%= ?I want link to single months archive here? %>
I'm creating a blog in rails and I thought I would add an archive section that you commonly see in the sidebar of many blogs. When I navigate to the posts#month
view it displays the month as a heading and lists all the posts made during that month.
What I want to do now is have a list of months that posts where made on the posts#index
view with each month linked to the posts#month
view described above.
I'm not sure what to put on the posts#index
view to accomplish this. Any ideas on what to put there or a better way to implement this would be great.
Any help appreciated!
Upvotes: 0
Views: 1482
Reputation: 215
In case someone try this for Postgres, the above method will not work.
def by_year_and_month
@posts = Post.where("YEAR(created_at) = ? AND MONTH(created_at) = ? ", params[:year], params[:month]).order("created_at DESC")
end
so you can do it like this,
def by_year_and_month
@posts = Post.where('extract(year from created_at) = ?', params[:year]).where('extract(month from created_at) = ?', params[:month]).order("created_at DESC")
end
Hope this will help someone.
Upvotes: 2
Reputation: 7160
I am always do it by this way for grouping:
@posts_by_month = Post.find(:all, :order => "created_at DESC").group_by { |post| post.created_at.beginning_of_month }
Then create for example posts/_post_archive.html.erb
:
<div id="post-archive">
<% @posts_by_month.each do |month, posts| %>
<h4><%= "#{month.strftime('%B %Y')} (#{posts.count}):" %></h4>
<ul>
<% for post in posts %>
<li><%= link_to post.title, post %></li>
<% end %>
</ul>
<% end %>
</div>
And where it will be needed write this <%= render :partial => "posts/post_archive" %>
UPDATE:
In your controller create action:
def by_year_and_month
@posts = Post.where("YEAR(created_at) = ? AND MONTH(created_at) = ? ", params[:year], params[:month]).order("created_at DESC")
end
In your routes.rb
:
match 'posts/by_year_and_month/:year/:month' => 'posts#by_year_and_month', :as=> :posts_by_year_and_month
And modifying our posts/_posts_archive.html.erb
:
<h4><%= link_to "#{month.strftime('%B %Y')} (#{posts.count}):", posts_by_year_and_month_path(:year=> month.year, :month => month.month) %></h4>
Upvotes: 2
Reputation: 5111
In PostsController
def index
@posts = Post.published
@grouped_posts = Post.select("COUNT( * ) AS posts, MONTHNAME( created_at ) AS MONTH , YEAR( created_at ) AS YEAR").group("MONTH, YEAR").order("YEAR, MONTH( created_at )")
respond_to do |format|
format.html # index.html.erb
format.json { render json: @posts }
end
end
and then in view index.html.erb
<h1>Listing posts</h1>
<%grouped_posts.each do |rec|%>
<%=link_to "#{rec.month} #{rec.year} (#{rec.posts})", {:controller => "posts", :action => "month", :month => rec.month, :year => rec.year} %>
<%end%>
<%= render :partial => @posts %>
<h2>Blog archive</h2>
<%= ?I want link to single months archive here? %>
And then change the month action in posts_controller to accept two parameters params[:month] & params[:year]
Hope this will help
Upvotes: 0