個人的勉強メモ置き場

プログラミングど素人のメモ置き場

月間アーカイブ機能の作成[Rails6]

ブログには必須の月間アーカイブ機能を作ります

f:id:zykb:20220120045737p:plain

メソッドの作成
# Article.rb
def divide_monthly
    return Article.group("strftime('%Y%m', articles.created_at)")
                        .order(Arel.sql("strftime('%Y%m', articles.created_at) desc"))
                        .count
end


orderに直接SQLを指定するとエラーが出る(SQLインジェクション対策)のでArel.sqlで囲む。リクエストパラメーターなどには適用しない方がいいとのこと

qiita.com

PostgreSQLではstrftimeが使えないのでto_charを使います

# Article.rb
def divide_monthly
    return Article.group("to_char(created_at, 'YYYYMM')")
                        .order(Arel.sql("to_char(created_at, 'YYYYMM') desc"))
                        .count
end


view用にhelperを作成します

module ApplicationHelper
  def ymconv(yyyymm, cnt)
    yyyy = yyyymm[0,4]
    mm = yyyymm[4,2]
    yyyy + "" + mm + "月 (" + cnt + ")"
  end
end

view

<ul>
  <% @archives.each do |yyyymm, count| %>
    <li>
      <%= link_to ymconv(yyyymm, count.to_s), articles_path(year_month: yyyymm) %>
    </li>
  <% end %>
</ul>

f:id:zykb:20220120045744p:plain

@archivesはこのような形になってるので3回ブロック内が繰り返されます

controller

def index
  @archives = Article.divide_monthly
  if params[:year_month]
    @yearmonth = params[:year_month]
    @articles = Article.where("to_char(created_at, 'YYYYMM') = '"+@yearmonth+"'").page(params[:page])
  else
    @articles = Article.recent.page(params[:page])
  end
end


params[:year_month]の有無でindexの内容を変えています。categoryの時とほぼ同じ

zykbgame.hateblo.jp

月間アーカイブ的なのが出来ました

f:id:zykb:20220120051200g:plain