簡體   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