在Rails 4控制器

时间:2015-12-10 17:47:14

标签: ruby-on-rails ruby

我想在我的控制器中声明一些将由其父类中的方法使用的值。做这个的最好方式是什么?我的父控制器有一个提供分页的index方法,例如:

class BaseController < ApplicationController
  def index  
    @collection = model_class.paginate(page: params[:page], per_page: @per_page || 50) # I want this per_page value to come from the child controller, or use 50 if it's not set
  end

  private

  def model_class
    @model_class ||= controller_name.classify.constantize
  end
end

class ChildController < BaseController

end

ChildController中的哪个位置最好设置@per_page值,如何实现?我会有很多儿童控制器,所以我正在寻找最直接的方式。

我唯一的想法是将其从@per_page更改为per_page,然后在每个子控制器中定义此方法:

def per_page
  20 # Or whatever value is needed for that controller
end

我想我还需要在父控制器中定义这个方法来提供默认值,所以看起来像这样:

class BaseController < ApplicationController
  def index  
    @collection = model_class.paginate(page: params[:page], per_page: per_page) # I want this per_page value to come from the child controller, or use 50 if it's not set
  end

  private

    def per_page
      50
    end

    def model_class
      @model_class ||= controller_name.classify.constantize
    end
end

class ChildController < BaseController
  private

    def per_page
      20
    end
end

这有更好的模式吗?

4 个答案:

答案 0 :(得分:1)

您可以将它添加到您的Rails应用程序机密上,并在每次需要该值时使用它,也就是说,如果该值不会动态更改。

我在db中创建了一个名为app_configurations的表,其中存储了所有这些值。只有当您让客户更改管理页面中的值或其他内容时才会建议这样做(因此他不会经常通过这么少的更改来打扰您)

如果您认为这些选项不好,您可以使用您想要的方法创建一个Ruby模块,并将其包含在您想要的控制器中:

module Pagination
  def per_page
    50
  end
end

然后

include Pagination

答案 1 :(得分:1)

如果你想在控制器中设置一个“默认”(我没有看到你正在使用哪个分页宝石的任何上下文),你可以使用class variable

#app/controllers/base_controller.rb
class BaseController < ApplicationController
   @@per_page = 50
end

这将设置变量(与实例变量不同,因为无论是否已调用该类,它都可用)。此值将作为您可以构建的默认

#app/controllers/child_controller.rb
class ChildController < BaseController
   private

   def per_page
      @@per_page || 20 #-> if the "default" is not set, put it to 20
   end
end

-

如果您使用的是will_paginate - 或者我认为kaminari也是这样做的 - 您可以在应用配置之前设置per_page默认值整个应用程序加载:

#config/application.rb
...
WillPaginate.per_page = 50

Kaminari很相似,虽然我现在已经丢失了代码。

答案 2 :(得分:0)

您可以编写模块并使用类方法设置per_page,就像下面的代码一样:

<强>控制器/关切/ paginate_concern.rb

  require 'active_support/concern'

  module PaginateConcern
    extend ActiveSupport::Concern

    included do
      set_per_page 50 # default 50
    end

    class_methods do
      def set_per_page(value)
        append_before_action {
          @per_page = value
        }
      end
    end
  end

<强> base_controller.rb

    class BaseController < ApplicationController
      include PaginateConcern
    end

<强> child_controller.rb

  class ChildController < BaseController
    set_per_page 20 # override 50 to 20

    def index
      @children = Children.paginate(page: params[:page], per_page: @per_page)
    end
  end

答案 3 :(得分:0)

回答有点迟,但我在我的应用程序中做了类似的事情。如果您正在使用 will_paginate gem,只需为其创建一个名为will_paginate.rb的初始化程序,并在其中添加以下行:

WillPaginate.per_page = 50

同样的方法也在Wiki中提到了gem。如果要覆盖此默认值,只需在模型中进行自定义,而不是在控制器中进行自定义。模型级别设置将在model.rb文件中进行,如下所示:

self.per_page = 10

现在,当模型特定设置不存在时,它将使用全局设置。