2
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

kaminariで `+`を使い配列化するとundefined method `page'が発生する

Last updated at Posted at 2018-12-21

はじめに

kaminariでページネーションを実装していた際、エラーで怒られたのをまとめます。

再現手順

kaminariを使ってページネーションを実装しようとする。
この場合は、新しいUserが先に来るように配列を並び替えて、

xxx_controller.rb
new_user = User.where(flag: 0).order("created_at desc")
old_user = User.where(flag: 1).order("created_at desc")
@users = new_user + old_user
@users.page params[:page]

こんな感じで書くと、下記のような感じでエラーが発生する。

NoMethodError - undefined method `page' for #<Array:0x007f8dfd8f2518>:

2018/12/22 追記
@asm さんからご指摘頂きました!

@users = User.where(flag: 0).or(User.where(flag: 1)).order("created_at desc")
@users.page params[:page]

このような書き方をすることによって、そもそも+によって@usersが配列化しないので、より簡潔に書くことができます。

原因

kaminariのpageメソッドは、ActiveRecord::Relationオブジェクトを受け取ってActiveRecord::Relationオブジェクトを返す。

pageメソッドの中身はこんな感じ。

active_record_model_extension.rb
# frozen_string_literal: true

require 'kaminari/activerecord/active_record_relation_methods'

module Kaminari
  module ActiveRecordModelExtension
    extend ActiveSupport::Concern

    included do
      include Kaminari::ConfigurationMethods

      # Fetch the values at the specified page number
      #   Model.page(5)
      eval <<-RUBY, nil, __FILE__, __LINE__ + 1
        def self.#{Kaminari.config.page_method_name}(num = nil)
          per_page = max_per_page && (default_per_page > max_per_page) ? max_per_page : default_per_page
          limit(per_page).offset(per_page * ((num = num.to_i - 1) < 0 ? 0 : num)).extending do
            include Kaminari::ActiveRecordRelationMethods
            include Kaminari::PageScopeMethods
          end
        end
      RUBY
    end
  end
end

include Kaminari::ActiveRecordRelationMethodsしてますね。
GitHub - kaminari/kaminari

コンソールで違いを見てみると、

pry(main)> new_user.class
=> User::ActiveRecord_Relation

pry(main)> user.class
=> Array

このようにオブジェクトが変わっていることがわかる。

解決方法

えー、Arrayに対してどうすればいいんだ、、、、
とうちひしがれてたら、しっかり解決策がありました。

@paginatable_array = Kaminari.paginate_array(my_array_object).page(params[:page]).per(10)

なので、

xxx_controller.rb
new_user = User.where(flag: 0).order("created_at desc")
old_user = User.where(flag: 1).order("created_at desc")
users = new_user + old_user
@users = Kaminari.pagenate_array(users).page(params[:page]).per(10)

のように書けば解決!!

参考

kaminari/kaminari
kaminari徹底入門
【Rails】kaminariさんって配列もいけるんですね

2
0
3

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?