【问题标题】:will-paginate broken with Rails 5.1?Rails 5.1 会破坏分页吗?
【发布时间】:2018-12-14 14:58:27
【问题描述】:

自从升级到 Rails 5.1 后,我在尝试对未过滤(但未过滤)的用户表结果进行分页时收到以下错误:

我使用 will-paginate 3.1.6 和 Rails 5.1.0。我什至不确定是哪一行导致了错误;大概就是这条线

format.html { @members = @members.page(params[:page]); render }

因为在错误的正上方,我看到一个数据库调用询问偏移量为 25 限制为 25 的用户。

我什至尝试为(标准 ActiveRecord)User 模型创建一个empty? 方法,但这会将错误更改为抱怨这不是字符串。

我需要更改对 will_paginate 的调用吗?我需要早期版本的 will_paginate 吗?如何让它与 Rails 5.1 一起工作?

编辑:这就是@members 的填充方式:

@members = User.order("id DESC")
if current_user.admin_level < 8
    @members = @members.where("country = ?", current_user.country)
end

【问题讨论】:

  • 您似乎将 User 模型的一个实例传递给 will_paginate,因为它需要 ActiveRecord 关系。你能添加你的控制器和视图逻辑吗?
  • 你能添加整个控制器方法吗?
  • @abM 我刚刚添加了创建 ActiveRecord 关系的代码。
  • 如果您不确定导致错误的原因,很可能您没有向我们显示导致错误的代码。请创建一个 executable example,就像 Benj 为 this question 所做的那样。甚至可以将use his 作为一个注视点。

标签: ruby-on-rails will-paginate ruby-on-rails-5.1


【解决方案1】:

错误很可能在于您将User 的单个实例传递给page_entries_info 而不是集合(您没有提供视图和整个控制器操作,所以很难说)

错误的可执行示例如下所示:

#!/usr/bin/env ruby
# frozen_string_literal: true

require "bundler/inline"

install = true
gemfile(install) do
  source "https://rubygems.org"
  gem "rails", "5.1.0"
  gem "will_paginate", '3.1.6'
  gem "sqlite3"
end

require "active_record"
require "action_controller/railtie"
require "will_paginate"
require "logger"
require "rack/test"

# we are skipping initializers so include manually:
require 'will_paginate/active_record'
require 'will_paginate/view_helpers/action_view'

ActiveRecord::Base.establish_connection(adapter: "sqlite3", database: ":memory:")
ActiveRecord::Schema.define do
  create_table :users, force: true do |t|
    t.string :country
  end
end

class User < ActiveRecord::Base
  self.per_page = 25
end

class TestApp < Rails::Application
  config.root = __dir__
  config.session_store :cookie_store, key: "cookie_store_key"
  secrets.secret_key_base = "secret_key_base"

  config.logger = Logger.new($stdout)
  ActiveRecord::Base.logger = config.logger
  Rails.logger  = config.logger

  routes.draw{ get "/" => "members#index" }
end

class MembersController < ActionController::Base
  include Rails.application.routes.url_helpers

  def index    
    @members = User.order("id DESC")
    @members = @members.page(params[:page])
    respond_to do |format|
      format.html{
        # passing single instance instead of collection:
        render inline: "<%= page_entries_info(@members.first) %>"
      }
    end
  end
end

require "minitest/autorun"

class BugTest < Minitest::Test
  include Rack::Test::Methods

  def test_returns_success
    User.create!
    get "/?page=1"
    assert last_response.ok?
    puts last_response.body
  end

  private
    def app
      Rails.application
    end
end

【讨论】:

    【解决方案2】:

    我认为你应该改变

    @members = @members.page(params[:page])
    

    @members = User.page(params[:page])
    

    但这当然取决于 @members 的设置。如果您之前根据某些搜索条件将@members 设置为Users 数组,则不应实例化User 对象,而应将关系保留在@members 中。

    【讨论】:

    • 查看我的帖子,现在已编辑以包含填充成员的代码。
    • @Sprachprofi 您还需要发布您的视图模板的相关部分,以便我们可以看到@members 是如何呈现的。
    【解决方案3】:

    更改您认为导致问题的行(在您的控制器中):

    format.html { @members = @members.page(params[:page]); render }

    对此(如果您也使用 JavaScript):

    @members = Member.paginate(page: params[:page]).order("id DESC")
    respond_to do |format|
      format.html
      format.js
    end
    

    或者这个(如果你更愿意使用原版的话):

    format.html { @members = Member.paginate(page: params[:page]); render }

    在你看来,尝试这样的事情:

    <% if current_user.admin_level < 8 %>
      <%= will_paginate @members.where("country = ?", current_user.country) %>
    <% end %>
    

    【讨论】:

      【解决方案4】:

      可能不是这样,但是I've been reading the gem in question 而且,不应该是……?:

      format.html { @members = @members.paginate(page: params[:page]); render }
      

      【讨论】:

      • page 是正确的。请参阅“Active Record 3 中的新功能”下的链接或the wiki
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多