在控制器方法中干掉类似的代码

时间:2017-02-17 12:27:42

标签: ruby-on-rails dry

我在控制器中有两个方法,代码非常相似。想知道我怎么能干它们!他们都使用csv-importer gem来解析csv文件。

sales_controller.rb

  def import_csv_test
    user_id = params[:user_id]
    import = ImportSaleCSV.new(file: params[:file]) do
      after_build do |sale|
        sale.user_id = user_id
        skip! if sale.email == nil
        skip! if sale.order_date == nil
        skip! if sale.amount == nil
      end
    end
    import.run!
    redirect_to lifecycle_grid_sales_path, notice: import.report.message
  end

  def import_ftp
    user_id = params[:user_id]
    import = ImportSaleCSV.new(path: './public/uploads/gotcha.csv') do
      after_build do |sale|
        sale.user_id = user_id
        skip! if sale.email == nil
        skip! if sale.order_date == nil
        skip! if sale.amount == nil
      end
    end
    import.run!
    redirect_to lifecycle_grid_sales_path, notice: import.report.message
  end

谢谢!

2 个答案:

答案 0 :(得分:0)

您可以将您的方法重构为单一方法:

def import(hash)
  user_id = params[:user_id]
  import = ImportSaleCSV.new(hash) do
    after_build do |sale|
      sale.user_id = user_id
      skip! if sale.email == nil
      skip! if sale.order_date == nil
      skip! if sale.amount == nil
    end
  end
  import.run!
  redirect_to lifecycle_grid_sales_path, notice: import.report.message
end

然后叫它:

import({file: params[:file]})
import({path: './public/uploads/gotcha.csv'})

似乎该方法不属于您的控制器,因此您可能希望将其提取到某处。我建议您检查this great article并将您的方法提取到全新的服务对象中。

答案 1 :(得分:0)

我认为你可以提取一个班来完成繁重的工作。

class ImportSaleCSVCreator
  def initialize(csv_options = {}, csv_attributes = {})
    @csv_options = csv_options
    @csv_attributes = csv_attributes
  end

  def build
    ImportSaleCSV.new(csv_options) do
      after_build do |sale|
        csv_attributes.each { |k, v| sale.public_send("#{k}=", v) }
        skip! if sale.email.nil? || sale.order_date.nil? || sale.amount.nil?
      end
    end
  end

  private

  attr_reader :csv_options, :csv_attributes
end

class Controller
  def import_csv
    import = ImportSaleCSVCreator.new({ file: params[:file] }, { user_id: params[:user_id] })
    import.run!
  end

  def import_ftp
    import = ImportSaleCSVCreator.new({ path: './gotcha.csv' }, { user_id: params[:user_id] })
    import.run!
  end
end

确保检查传递的属性。特别是在处理文件,路径等时。您可能希望过滤ImportSaleCSVCreator中的参数。