アラフォーがお金持ちになるためプログラマ目指すブログ

お金も根性も学歴もないアラフォーまきのがエンジニア…じゃない、プログラマになってお金持ち目指すよ!

【Railsメモ】ページネーション will_paginateとbootstrap-will_paginateとacts-as-taggable-on

めも!


FAQのページ、acts-as-taggable-onが入っているんだけれど、ここでpaginationしたかった。

1:acts-as-taggable-on


これは↓の時に実装してた。
細かいやり方はあとで…って全然書いてないな;

www.arafo-enjineer.net


参考①
github.com


参考②
ruby-rails.hatenadiary.com


1:GemFileにgem加筆

gem 'acts-as-taggable-on'


2:bundle install

$ bundle install


3:テーブル作る

$ rails acts_as_taggable_on_engine:install:migrations

して

$ rails db:migrate


4:対象のモデルにacts_as_taggable_onを使うよと書いてあげる


【models/faq.rb】

acts_as_taggable
acts_as_taggable_on :categories


私は実際こんな風にかいた。

f:id:MmRevorution:20190607132143p:plain



9行目はコメントにも書いてあるけれど、acts_as_taggable_on :tagsのエイリアスとして必要なんだそうだ。
なんで必要なのかは…理解できず(悲)



ただ、これを書くことでcategories_listってのと、tag_listというメソッドが使えるようになるそう。




あと、categoriesは、ご覧の通り私の場合FAQでタグを使いたくて、カテゴリーをタグにするのが自然な感じだったから。




参考サイト②ではlabelsと書かれていた。
参考サイト①GitHubでは以下のようになっているので、対象カテゴリを作ることもできるみたい。

:
acts_as_taggable_on :skills, :interests
:



ちなみにテーブルはこんなの。
(FQAをいくつか登録したあと/ pgAdminの画面)


【tagging】

f:id:MmRevorution:20190607125506p:plain

taggable-typeをみると、望み通りFaqと連携されてるのがわかる。
contextではFaqモデルに書いたcategoriesが反映されてる。




【tag】

f:id:MmRevorution:20190607125503p:plain



こっちはタグ全体の管理って感じがする。
idが一つなのは、私がcategoriesの1つしかタグを作ってないから。




nameはタグの名称。今回はテストのためわかりにくいけれどaというカテゴリってことにしてFAQを登録してたからaってなってる。




taggings_countは、そのタグが何件使われているか。
今登録しているFAQのうち6つにaというタグがつけられてる。




さらに因むと、schemaはなんだかすごくたくさん書かれてるw

f:id:MmRevorution:20190607131150p:plain




5:controllerに書いてあげる

【controllers/faqa_controller.rb】

def index
    if  params[:tag]
      @faqs = Faq.tagged_with(params[:tag])
    else
      @faqs = Faq.all
    end
end

ifで分岐しているのは、タグで絞り込みできるようにするため。



余談だけれど、faqに限らず絞り込みはこうやってif params [:カラム名とか]と書ことで作ることができるんだね。
絞り込みの考え方面白いw




他のページでも絞り込み作ってあるけれど、最初は一体どうやって絞り込んでデータを受け取ればいいんだろう?って謎だった。




というわけで、選択されたタグと同じタグを持つデーターだけをFaqのなかから拾って@faqsに格納してくれるようにしてある。




elseは絞り込みがない場合。だからFaq.allで全てのデーター拾ってくるようになってる。




6:viewに書いてあげる

【views/faqs/index.html.erb】

<% @faqs.each do |faq| %>
 <div class="card bg-light mb-2">
  <div class="card-body">
   <h5><%= link_to(faq.questions, "/faqs/#{faq.id}") %></h5>
   <h6>このQAのカテゴリー:<%= raw faq.category_list.map { |t| link_to t, tag_path(t)}.join(',') %></h6>
  </div>
 </div>
<% end %>


FAQにあててるので、まずFAQの一覧にeachでぐるぐるして1つずつ表示する時に、タグ(カテゴリ)が出るようにしてみた。




h6の部分が、acts-as-taggable-onを活用している部分。
ここでは、そのQAにつけられているタグをcategory_listを使って表示してる。




こんな感じ

f:id:MmRevorution:20190607133601p:plain



ちな、2行目3行目はBootstrapのカードの記述。
カードにFAQ入れていくスタイルにしていたため。
(この後テーブルに変更するのでちょっと変わる予定)



それとこれ

【views/faqs/index.html.erb】

<div class="card-body">
 <div id="tag_cloud">
  <% tag_cloud Faq.category_counts, %w{s m l} do |tag, css_class| %>
   <%= link_to tag.name, tag_path(tag.name), class: css_class %><br/>
  <% end %>
 </div>
</div>


これはタグ一覧を全て表示して、カテゴリで絞り込みができるようにしてあるもの。



こんな感じ

f:id:MmRevorution:20190607133911p:plain


2行目3行目にある通りtag-cloudってのも導入してみてる。
たくさん使われているカテゴリほど、大きな文字で表示されるというもの。




いまはまだクリック数が皆無なので大きさの違いは出ないけれど、プロトタイプで試した時はこんな感じになった。


f:id:MmRevorution:20190607134649p:plain


全般・テストは一番大きな文字
MOKUタグが中くらい
それ以外が一番しいさな文字




でもこれも使って見たいからって導入してて、ユーザーからするとちょっと使い勝手悪いかもしれないので、いずれ無くしてしまうかもしれない。




ざっと書くとこんな感じだった気がする。


2:ページネーション

カードにしてるせいもあって、かなりページが長くなっちゃう。



この後テーブルにするから、多少スッキリはするだろうけれど、せっかくだからもうちょっとなにか挑戦したくって、一般的によく使われるページネーションを導入することに。




参考①
qiita.com

参考②
qiita.com

参考③
github.com



1:GemFileにgem加筆

gem 'will_paginate'
gem 'bootstrap-will_paginate'

will_paginateだけでページネーションはできるんだけど、ページめくりのボタンをかっこよくしたかったので、bootstrap-will_paginateも一緒に導入。




2:bundle install

$ bundle install




3:controllerに書いてあげる


私の場合、acts-as-taggable-onさんがすでにいらっしゃるので、足りない頭をこねくり回してこのようにしたらうまくいった。


【controllers/faqs_controller.rb】

<参考サイト②>

def book_list
   @books = Book.paginate(page: params[:page], per_page: 5)
end


<私のコード:元>

def index
    if  params[:tag]
      @faqs = Faq.tagged_with(params[:tag])
    else
      @faqs = Faq.all
    end
end


<私のコード:新>

def index
    if  params[:tag]
      @faqs = Faq.tagged_with(params[:tag]).paginate(page: params[:page], per_page: 5)
    else
      @faqs = Faq.paginate(page: params[:page], per_page: 5)
    end
end




4:viewを書いてあげる


この2つの参考には以下のように1行加筆でOKってある。


<%= will_paginate @model %>

でもうまくいかなかった私。





これでももちろんページネーションそのものは大丈夫なんだけれど、これだけだとbootstrapさんのかっこいいフォームが反映されなくて、こんなんになる。


f:id:MmRevorution:20190607140517p:plain




英語になってるのはこの後の手順で直すとして、なんじゃこりゃ。
ラベル12ってなんだよ。




と思ったら、previous_label1ページ目2ページ目next_labelだったw
見辛いw




そこで参考③のGitHubを確認したところ、以下のようにかけばOKとわかった。


【faqs/index.html.erb】

<%= will_paginate @faqs, :renderer => WillPaginate::ActionView::Bootstrap4LinkRenderer %>


:renderer => WillPaginate::ActionView::Bootstrap4LinkRendererをオプションとして書いてあげるだけ。





あと、日本語にするんだけれど、そこで別に前へとか次ページへとか書かなくていいよなと思ったので、以下のように。


【config/locales/environment.rb】

WillPaginate::ViewHelpers.pagination_options[:previous_label] = '&laquo'
WillPaginate::ViewHelpers.pagination_options[:next_label] = '&raquo'

設定ファイルなので、加筆修正した場合は必ずRailsを再起動すること。





あと、ここで初めて知ったけれど、<とか>って特殊文字だったんだね。




普通に>>って書けばいいと持ってたのでこれも発見だった。
スペースをスペースのままコードに書くのはよろしくないというのは教わったので、その特殊文字はわかったんだけれど記号も特殊文字がいいんだな…。

www.htmq.com



で、こうなった。

【旧】

f:id:MmRevorution:20190607140517p:plain



【新】

f:id:MmRevorution:20190607141516p:plain




おしまい!