😽
【Rails】will_paginateを使用時にgonの中身が更新されない問題
概要
will_paginateを用いて、ページの切り替えを行った際に渡されるgonの中身が更新されない問題が発生したので、その原因と対処法をメモ。
gonについて
gonについての使い方は下記のURLがわかりやすいので省略
原因
ページの切り返しに、gonの更新が行われないのは、turbolinksが有効だったために更新されなかった。
turbolinksとは、簡単にいうとjs, cssの読み込みを初回時に行い次回以降の読み込み処理を省略することで高速化する処理をしているのものだ。
おそらくこれが悪さをしている。
対処法(面倒)
一番はページの切り返しにturbolinksをfalseにすること。
ただし、これは簡単にはできない。
下記のようにレンダラーをカスタムすることでしか実現できないのだ
config/initializers/custom_renderer.rb
require 'will_paginate/view_helpers/action_view'
require 'will_paginate/view_helpers/link_renderer'
class CustomPaginateRenderer < WillPaginate::ActionView::LinkRenderer
def container_attributes
{ class: 'pagination' }
end
def html_container(html)
child = tag(:ul, html, container_attributes)
tag(:nav, child)
end
def page_number(page)
if page == current_page
'<li class="page-item active" data-turbo="false">' + link(page, page, rel: rel_value(page),class: 'page-link') + '</li>'
else
'<li class="page-item" data-turbo="false">' + link(page, page, rel: rel_value(page),class: 'page-link') + '</li>'
end
end
def previous_page
num = @collection.current_page > 1 && @collection.current_page - 1
previous_or_next_page(num, '<span aria-hidden="true">«</span>')
end
def next_page
num = @collection.current_page < total_pages && @collection.current_page + 1
previous_or_next_page(num, '<span aria-hidden="true">»</span>')
end
def previous_or_next_page(page, text)
if page
'<li class="page-item" data-turbo="false">' + link(text, page, class: 'page-link') + '</li>'
else
'<li class="page-item disabled" data-turbo="false">' + link(text, page, class: 'page-link') + '</li>'
end
end
end
application_helper.rb
def will_paginate(coll_or_options = nil, options = {})
if coll_or_options.is_a? Hash
options = coll_or_options
coll_or_options = nil
end
unless options[:renderer]
options = options.merge renderer: CustomPaginateRenderer
end
super *[coll_or_options, options].compact
end
正直ちょっとめんどくさい。他への影響もわからないし。。。
対処法(簡単)
だったら、毎回読み込まれるような位置に= Gon::Base.render_data
を配置しとけば、もしかして毎回読み込まれるのでは?と仮説を立ててみると、以下のようなissuesがHit。
なるほど、bodyタグ内で定義してしまえばいいのか!
sample.slim
doctype html
html
head
title 管理画面
= csrf_meta_tags
= csp_meta_tag
= stylesheet_link_tag 'cms/application', media: 'all', 'data-turbolinks-track': 'reload'
= javascript_include_tag 'cms/application', 'data-turbolinks-track': 'reload'
body
# 省略
= Gon::Base.render_data
解決した。
まとめ
たまには楽しても....いいよね。。。笑
Discussion