2017-03-02 12 views
1

Rails 5アプリケーションでは、ユーザーが入力したパラメータに従ってn個のレコードを作成するbulk_create関数を呼び出すajax put要求があります(これは魅力的です)。技術的には、生成されたばかりのデータを使用してCSVファイルも生成する必要があります。CSVファイルがRails 5アプリケーションでエクスポートされていない

AJAXコール:私のコントローラで

$('.bulk-button').on('click', function(){ 
    $.ajax({ 
     type: 'post', 
     url: '/admin/coupons/bulk-create?number='+$('#bulk-number').val() 
    }); 
}); 

:私のモデルでは

def bulk_create 
    iterations = params[:number].to_i 
    i = 0 
    sequence = [('a'..'z')].map(&:to_a).flatten 
    while i < iterations do 
     name = (0...6).map { sequence[rand(sequence.length)] }.join 
     Coupon.create(:name => name, :value => 10, :coupon_type => 'amount', :limit => 1, :expiration_date => Date.current + 365) 
     i+=1 
    end 

    coupons = Coupon.order('created_at DESC').limit(iterations) 

    respond_to do |format| 
     format.html { redirect_to(admin_coupons_path) } 
     format.csv { send_data coupons.to_csv } 
    end 
end 

def self.to_csv(options = {}) 
    desired_columns = ["name", "value"] 
    CSV.generate(options) do |csv| 
    csv << desired_columns 
    all.each do |coupon| 
     csv << coupon.attributes.values_at(*desired_columns) 
    end 
    end 
end 

私はコンソールで生成されたエラーを参照してください、まだありませんありませんCSVファイルがエポートされています。どんな推測?

ありがとうございます!あなたがそこにある必要はありませんあなたのコード内のいくつかの合併症を持っている

+0

URLに.csvを使用してみましたか? '/admin/coupons/bulk-create.csv?number = ...' – yoavmatchulsky

+0

まず、モデルで定義されている 'self.to_csv'は、コントローラで' coupons.to_csv'を呼び出すときに呼び出されるものではありません。コントローラーのクーポンはActiveRecordクラスであり、クーポンクラスメソッドにアクセスすることはできません。一般に、to_csvはより多くの書式設定/レンダリングタイプの操作を行っているので、最初にモデル上で定義するべきではありません。新しいクラスを作成する必要があります(たとえば、CouponsCsv?)、その上にto_csvメソッドを記述します。さらに良いことに、おそらくこの問題のためにそこに宝石があります。また、上記のコメントによると、リクエストは.csvなしで処理されません。 – Glyoko

答えて

0

問題はAjaxであることが判明しました。私はいくつかの記事で、実際にajaxがcsvのダウンロードに気を遣うということを読んだ。私は単純なform_tagでajax呼び出しを置き換え、それはすべてうまくいった。

1

コード明快さとスタイル

について少し:範囲は、より直接的な方法で使用することができます。

sequence = ('a'..'z').to_a 

あなたはまた、あなたを与えるだろう、配列のランダムな要素を取得するために#sampleを使用することができます。

sequence.sample 

代わりの

sequence[rand(sequence.length)] 

#injectのすてきなタッチはとして役立つかもしれません複雑な構文を避けるためにオブジェクトの倍数の時間を与えることができます。 私たちは、このようにしています:あなたのエラーに関する

(0...5).inject(""){ |coupon_code| coupon_code << sequence.sample } 

別のビット

私の推測では、この方法to_csvの定義はクラスクーポン自体にであり、あなたはそれを呼び出していないということでしょう。ここであなたの可変クーポンは、配列のように動作するすべての可能性を持っているデータベースから取得されたクーポンのコレクションです。配列がto_csvをどのように処理するかを見てみましょう。

[].to_csv # => "\n" 
[Coupon.first, Coupon.first].to_csv 
# => "#<Coupon:0x007f81ca4d2558>, #<Coupon:0x007f81ca4d2558>\n" 

Array.to_csvは、それぞれの要素に対してto_sを呼び出し、すべてをcsvセパレータで結合しているようです。ここで取得したメソッド呼び出しはコード内の適切な場所にあり、to_csvはArrayがサポートしているのでエラーを発生させません!

+0

'Coupon.order( 'created_at DESC')。limit(iterations)'は実際には配列ではなくActiveRecordの関係オブジェクトを返しますが、そうでなければ良い答えです。また、注入行のビットをさらに改善するために、 '6xinject(" "){| coupon_code | coupon_code << sequence.sample} ' – Glyoko

+0

コードを改善する方法についてお寄せいただきありがとうございます。確かに.to_csvが存在していて、ファイルがダウンロードされなくても応答で返されたcsv応答を見ることができます。 @Gyoko - 私もいくつかの宝石(特にascsv)を使ってみましたが、これまで以上に多くのエラーが発生していました。残念ながら –

+0

のドキュメントはほとんどありませんまた、私のモデルでself.to_csvメソッドを削除しようとしました。 (#のための未定義メソッド 'to_csv ' ): つまり、実際にはcoupons.to_csvを呼び出すと、self.to_csvが呼び出されます。 –

関連する問題