繁体   English   中英

Rails:清理控制器中的大型方法

[英]Rails: Cleaning up large methods in controllers

还在学习如何重构我的一些控制器,并希望得到一些建议(我在代码块中留下了一些关于发生了什么的注释)。

我当前的实现工作正常,但我想知道是否有更好,更简单的方法来解决这个问题; 关于在方法中添加这么多实例变量以实现这样一个微不足道的事情。

class JobsController < ApplicationController

  def index
    ## records created through app that have been approved (published)
    @paid_jobs = Job.published

    ## records fetched from RSS feed
    @fetched_jobs = JobEntry.all

    ## creates an array of paid_jobs and fetched_jobs, and what is considered the 'feed'. would usually be order("published_at DESC") but you can't call order on an array
    @job = (@paid_jobs + @fetched_jobs).sort_by(&:published_at).reverse

    ## you can't show pagination links for a static array directly. you can, however, first paginate it
    @jobs = @job.paginate(:page => params[:page], :per_page => 10)

    ## this is the actual variable I call in the Job#index view lol
    @published_jobs = @jobs.group_by { |job| job.published_at.to_date }
  end

您可以使用rails功能单表继承(STI)。 这使您可以在一个表中存储类似的模型,因此您可以将常规作业和提取的作业存储在一个表中。 选择和分页现在非常简单,并且消除了ruby中任何自定义逻辑的所有需求。 这也可能会显着提高您的性能(取决于数据库记录的数量)。

请参阅官方文档: http//guides.rubyonrails.org/association_basics.html#single-table-inheritance

所以你要创建父类:

class Job < ActiveRecord::Base
  scope :published, -> { where(published: true) } # is inherited by all children
  scope :latest, -> { order(published_at: :desc) } # shortcut for ordering
  # you can add more scopes to enhance readability in controller

  # Job related logic inherited by all children
end

重要的是,此AR的表具有列type (字符串)。

然后从该父类派生两种作业类型:

class InternalJob < Job
  # InternalJob related logic
end

class FetchedJob < Job
  # FetchedJob related logic
end

现在,您可以将所有工作提取到您的心中,并在其上分页:

InternalJob.published # returns all published internal Jobs
FetchedJob.published # returns all published internal Jobs
Job.published # returns all Jobs

分页和排序很容易:

Job.published.sort_by(&:published_at).reverse.paginate(:page => params[:page], :per_page => 10)

当数据库进行所有过滤和排序时,这可以很好地扩展。

这也使您的控制器代码非常小:

def index
  @published_jobs = Job.published.latest.paginate(:page => params[:page], :per_page => 10).group_by do |job|
    job.published_at.to_date
  end
end

您可以尝试以下方法来清理代码

  1. 转到ActiveJob以在后台获取记录
  2. 使用ActiveSupport :: Concern将控制器的辅助方法保存在另一个文件中。 http://api.rubyonrails.org/classes/ActiveSupport/Concern.html
  3. 或者您可以使用Active Job保留cron作业并以json格式存储结果

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM