Ruby - 移动rails'业务逻辑'进入服务模块

时间:2015-05-14 09:57:31

标签: ruby-on-rails ruby

我想按照正确的OOP协议将一些rails业务逻辑转移到服务中。我按照此处推荐的方法:Private module methods in Ruby

最终,我希望将业务逻辑从模型和控制器转移到服务中,这些服务是Plain Old Ruby Objects。因此,模型只关注持久性,范围界定和&验证

这是制作服务模块的正确方法吗?

第2版:

module CategorizeJobs

  def self.fetch( location, category_name )
    c = Categorizer.new( location, category_name )
    c.get_jobs
  end

  class Categorizer

    def initialize(location, category_name)
      @location = location
      @category_name = category_name
    end

    def get_jobs
      job_ids = get_correct_jobs
      Category.includes(:jobs).where( jobs: { id:  job_ids } )
    end

    private

      def get_correct_jobs
        jobs = filter_by_location
        jobs = filter_by_category(jobs)

        jobs.collect(&:id)
      end

      def filter_by_category(jobs)
        return jobs unless @category_name.present?

        category = Category.where(name: @category_name).first
        if category
          jobs = jobs.where(category: category)
        end

        jobs
      end

      def filter_by_location
        if @location.present?
          jobs = get_jobs_at_location
        else
          jobs = Job.open
        end
      end

      def get_jobs_at_location(location)
        Job.joins(:location).within(20, origin: @location).open
      end

  end

end

版本1:

 module CategorizeJobs

  def self.fetch( location, category_name )
    c = Categorizer.new
    c.perform( location, category_name )
  end


  class Categorizer

    def perform( location, category_name )
      job_ids = get_correct_jobs(location, category_name)
      Category.includes(:jobs).where( jobs: { id:  job_ids } )
    end

    private

      def get_correct_jobs(location, category_name)
        jobs = filter_by_location(location)
        jobs = filter_by_category(jobs, category_name)

        jobs.collect(&:id)
      end

      def filter_by_category(jobs, category_name)
        return jobs unless category_name

        category = Category.where(name: category_name).first
        if category
          jobs = jobs.where(category: category)
        end

        jobs
      end

      def filter_by_location(location)
        if location
          jobs = get_jobs_at_location(location)
        else
          jobs = Job.open
        end
      end

      def get_jobs_at_location(location)
        Job.joins(:location).within(20, origin: location).open
      end

  end

end

1 个答案:

答案 0 :(得分:3)

有一个名为Aldous的gem可以帮助您在Rails应用程序中实现基于体系结构的服务对象。看看吧。

如果您需要有关如何使用它和构建应用程序的进一步帮助,可以查看thisthis以获取更多帮助。