Rails: очистка больших методов в контроллерах - PullRequest
0 голосов
/ 18 мая 2018

Все еще учусь реорганизовывать некоторые из моих контроллеров и хотел бы получить несколько советов (я оставил некоторые заметки в блоке кода относительно того, что происходит).

Моя текущая реализация работает нормально, но мне интересноесли есть лучший и более легкий способ приблизиться к этому;кое-что о добавлении этого множества переменных экземпляра в метод, чтобы осуществить такую ​​тривиальную вещь.

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

Ответы [ 2 ]

0 голосов
/ 18 мая 2018

Вы можете использовать функцию рельсов для наследования одной таблицы (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
0 голосов
/ 18 мая 2018

Вы можете попробовать следующие методы для очистки вашего кода

  1. Перейти к ActiveJob для извлечения записей в фоновом режиме
  2. Используйте ActiveSupport :: Concern, чтобы сохранить вспомогательные методы для контроллера в другом файле,http://api.rubyonrails.org/classes/ActiveSupport/Concern.html
  3. Или вы можете сохранить задание cron с помощью Active Job и сохранить результат в формате json
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...