【问题标题】:Paginate without a gem Next, Previous, buttons for Name.order(:id).limit(10).offset(0)没有 gem 的分页 Next、Previous、Name.order(:id).limit(10).offset(0) 的按钮
【发布时间】:2016-07-04 09:35:01
【问题描述】:

一个多星期以来,我一直在寻找解决问题的方法。我有一个作业,由于没有下一个/上一个功能,我失去了 10 分,而且时间用完了。不过我还是想弄清楚。

我用rails generate scaffold Ripple name:string message:text url:string 创建了一个简短的单页站点,它显示了 10 个最新帖子显示的索引(名称、消息、created_on、link_to“显示”)。我仍然必须创建下一个、上一个、最新、最旧的链接以显示下一个 10、上一个 10 .... 结果。我的代码。

app\controllers\ripple_controller.rb

class RipplesController < ApplicationController  
  before_action :set_ripple, only: [:show, :update]  
  before_action :restrict_destroy_edit, only: [:edit, :destroy]   
  before_filter :set_page   
  helper_method :link_name_to_url, :next_button, :previous_button, :newest_button, :oldest_button, :is_next_page_available, :is_previous_page_available

  RIPPLES_PER_PAGE = 10

  def index   
    @ripples = Ripple.order(:id).limit(RIPPLES_PER_PAGE).offset(@page * RIPPLES_PER_PAGE) 
  end
  #All my show, new, destroy, edit, create ....

  def next_button

  end

  def previous_button

  end

  def newest_button

  end

  def oldest_button

  end

  def is_next_page_available?

  end

  def is_previous_page_available?

  end

  def set_page 
    @page = 5 
  end
private
...

\app\views\ripples.html.erb

<table>
  <thead>
    <tr>
      <th>Name</th>
      <th>Message</th>
      <th>Posted</th>
      <th>Show Ripple</th>
    </tr>
  </thead>

  <tbody>
    <% @ripples.each do |ripple| %>
      <tr>
        <td><%= link_name_to_url ripple %></td>
        <td><%= truncate(ripple.message, length: 50) %></td>
        <td><%= ripple.created_at.strftime("%B %d, %Y %l:%M %P") %></td>
        <td><%= button_to 'Show', ripple, :method => "get" %></td>
      </tr>
    <% end %>
  </tbody>
</table>

<br>

<div id = "nav">
  <button><%= link_to 'Newest' %></button>
  <button><%= link_to 'Previous 10 Ripples' %></button>
  <button><%= link_to "Next 10 Ripples" %></button>
  <button><%= link_to 'Oldest' %></button>
  <button><%= link_to 'New Ripple', new_ripple_path, class: "button", method: :get %></button>
</div>

我尝试在 Model 中调用方法,但在下一个和上一个时不断收到 undefined method "next" for #&lt;Class:0xb4eabd0c&gt; 错误。

app\models\ripple.rb

class Ripple < ActiveRecord::Base
  default_scope -> {order(created_at: :desc)}
  validates :name, :message, presence: true
  validates :url, allow_blank: true, format: {
  with: URI::regexp(%w(http https)),
      message: "Must be a url starting with http:// or https://"
  }

  def next
    Ripple.order(:id).limit(10).offset((@page - 1) * 10)
  end

  def previous
    Ripple.order(:id).limit(10).offset((@page + 1) * 10)
  end
end

我将如何使用 order().limit().offset 实现下一个和上一个,并可能使用@page 来跟踪我在 ActiveRecord 中的位置。也许像

def next_button
  @page -= 1
end

无论哪种方式我都可以调用索引"&lt;%= link_to Next 10" next_button %&gt;,我没有可行的想法。

感谢您的帮助。

【问题讨论】:

  • 你可以使用宝石吗?如果是这样,will_paginate 会为您做所有事情,如果不是,请查看它的源代码。
  • undefined method "next" for #&lt;Class:0xb4eabd0c&gt; error on next and previous 你得到这个错误是因为你试图在课堂上打电话给instance method's。要使下一个和上一个方法在类级别可用,您需要在这些方法之前添加self。即def self.nextdef self.previous
  • 我希望我能拥有,我知道如何使用 will-paginate。但是不,我必须自己写,虽然我今天确实得到了提示,使用 session[:page] 而不是 @page。显然 rails 不会在视图和控制器之间传递 ruby​​ 变量。

标签: ruby-on-rails ruby ruby-on-rails-4 pagination


【解决方案1】:

这个怎么样?

class RipplesController < ApplicationController  
  before_filter :set_page, only: [:index]
  RIPPLES_PER_PAGE = 10
  def index   
    @ripples = Ripple.order(:id).limit(RIPPLES_PER_PAGE).offset(@page * RIPPLES_PER_PAGE) 
  end
  private
    def set_page
       @page = params[:page].to_i || 0
    end
end

然后在视图中的链接将是

<div id = "nav">
    <button><%= link_to 'Newest', ripples_path %></button>
    <button><%= link_to 'Previous 10 Ripples', ripples_path(page: @page - 1) %></button>
    <button><%= link_to "Next 10 Ripples", ripples_path(page: @page + 1) %></button>
</div>

所有这些都将通过RipplesController#index 方法驱动,并将使用/ripples?page=1/ripples?page=2 等URL。

这些link_to 调用将生成带有GET 变量的链接,以便您可以在params 哈希中访问它们并使用它们来驱动返回的结果。

【讨论】:

  • 这太棒了,这向我指出了一些我不知道的关于 Rails 的事情。一方面,我应该放弃像 java 一样对待它。谢谢你@engineersmnky。
  • 使用此方法在 link_to 中获取“无整数到字符串的隐式转换”。关于如何解决这个问题的任何想法?
  • @ncarroll 在set_page 中尝试@page = params[:page].to_i || 0
【解决方案2】:

这里有几件事。首先,控制器方法应该与匹配的路由一起使用。这是一个请求周期,您单击应用程序上的按钮,它向您的服务器发出请求,然后您的服务器响应信息。

当您以这种方式将 helper_method 设置为 helper_method 时,您的 next_button 方法将不起作用。为了使您的控制器工作,您应该有与您的控制器方法匹配的路由。在命令行中执行 rake routes。您需要在 route.rb 文件中看到类似的内容

get 'ripple/next', 'ripple#next'

更多关于routeshttp://guides.rubyonrails.org/routing.html#controller-namespaces-and-routing

在你的控制器中,你可以有

def next
  page = params[:page]
  params[:page] += 1
  @ripples = Ripple.find_ripples_on_page(page, PAGE_SIZE)
  render :index
end

那么在您的 erb 视图中,您应该“访问”这条特定路线,而不是调用该方法。

其次,您不能依赖模型中的类实例变量。相反,您应该将其放在会话中或作为查询字符串的一部分。如上控制器代码,我把它放在会话中,这是一个本地存储。更多关于sessionhttp://guides.rubyonrails.org/action_controller_overview.html#session

最后,你的模型。

def find_ripples_on_page(page, PAGE_SIZE)
  Ripple.where( ... ) # you can figure this out, depending on if you want to rank by updated_at or other filter
end

旁注:控制器中的helper_method 用于检索不向控制器发出命令的信息。这个宏所做的就是使用class_eval 并将控制器中的方法“复制”到renderer

如果可以使用 gem,请使用 will_paginate

http://guides.rubyonrails.org/routing.html#controller-namespaces-and-routing

【讨论】:

  • 哇,非常感谢。我在这个街区学到的东西比我在读的整本书中学到的还要多。这对我有很大帮助,因为这是我在 rails 中的第一个项目/第一次使用 Ruby,到目前为止我一直在使用 java 和 c#。不过很棒的学习经历。明天下班后我会实施这个,看看会发生什么。再次感谢您。
猜你喜欢
  • 2017-04-28
  • 1970-01-01
  • 2015-02-27
  • 2013-12-12
  • 2019-01-20
  • 2013-12-20
  • 2020-12-30
  • 2015-07-24
  • 2017-02-21
相关资源
最近更新 更多