2017-02-17 1 views
1

非常に似たコードを持つコントローラーには2つのメソッドがあります。どのように私はそれらを乾燥させることができますか?彼らは両方とも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 

ありがとう!あなたが単一のものにあなたの方法の両方をリファクタリングする

答えて

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をチェックし、新しいサービスオブジェクトにメソッドを抽出することをお勧めします。

+0

これは唯一の違いだと思われます。 –

+0

これは素晴らしいですね、ありがとう! 私のsales_controller.rbに直接インポートメソッドを定義しますか? これをこのように呼びますか? 'DEF import_csv_test インポート({ファイル:のparams [:ファイル]}) 終了 ' – AakLak

+0

うん、あなたはそれを行うことができます。メソッドがあなたのコントローラーに存在するはずはありません。だから、あなたはたぶんどこかでそれを抽出する必要があるでしょう。大きな選択肢は、単一のパブリックメソッド 'call'(' import'メソッドと全く同じ)といくつかのプライベートメソッドが必要な場合は、サービスクラスです。そのため、あなたのコントローラーでは、そのサービスのインスタンスを作成し、 'call'メソッドを呼び出すことができます。私はあなたのためのいくつかの便利なリンクで私の答えを編集します。 – VAD

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でパラメータをフィルタリングするとよいでしょう。

関連する問題