2016-10-19 7 views
0

CSVファイルを書き出すことができるRailsアプリケーションのコードがあります。値がないフィールドがあるレコードがない限り正常に動作します。その場合は失敗します。例えば、address_line_1を持たないユーザーがいるため、「No Method Error」と「address_line_1」を具体的に参照しています。しかしそれは一つの例です。本当にすべてのフィールドは潜在的な空白から保護されるべきです。コードは以下の通りです:Rails - 空白のフィールドがあるとCSVに失敗する

def download_kids_csv 

    @csv_headers = ['First', 
        'Last', 
        'Child First', 
        'Child Last', 
        'Parent Email', 
        'School', 
        'Class', 
        'Address', 
        'City', 
        'State', 
        'Zip', 
        'Parent Phone'] 

    @kid_data = [] 

    @school = School.find(params[:school_id]) 

    @school.classrooms.each do |classroom| 
     classroom.kids.includes(:users).each do |kid| 
      kid.users.each do |parent| 
       @kid_data << { 
        first: parent.first_name, 
        last: parent.last_name, 
        child_first: kid.first_name, 
        child_last: kid.last_name, 
        parent_email: parent.email, 
        school: @school.name, 
        class: classroom.classroom_name, 
        address: parent.addresses.first.address_line_1, 
        city: parent.addresses.first.city, 
        state: parent.addresses.first.state, 
        zip: parent.addresses.first.zip_code, 
        parent_phone: parent.phones.first.phone_number 
       } 
      end 
     end 
    end 

    respond_to do |format| 
     format.csv do 
      headers['Content-Disposition'] = "attachment; filename=\"#{@school.name.downcase.gsub(' ', '-')}-data.csv\"" 
      headers['Content-Type'] ||= 'text/csv' 
     end 
    end 
end 

答えて

0

[OK]この問題は、あなたがnil値でメソッドを呼び出しているためです。

ですから、例えばあなたが行うとき:あなたはそれがエラーをスローしますのでfirst_nameメソッドを実装していないこの

nil.first_name 

nilを行っているnilを

kid.first_name 

と子供があります。あなたが(そのちょっと醜い)これを回避するために何ができることは、この

kid.try(:first_name) 

ですこれは、あなたが以下の

parent.try(:addresses).try(:first).try(:zip_code) 
を行うことができ、これらの方法で行方不明のエラーこれらの長い鎖のために

を取得形成しなくなります

これは、頭痛の種をたくさん節約するはずですが、問題の根本的な原因は、データが空でないことを確認した場合に、このすべてを行う必要がないデータの完全性です。私はしかし、現実世界でそれは簡単に言ったことを理解する。 The Law of Demeterについての講義をしたり、オブジェクトにアクセスして属性にアクセスしないようにする方法、悪いデータ構成のコードがどのように拡散しているのか、そのスプレッドシート、時にはデータだけが必要な場合があります。がんばろう!

+0

恐ろしいです。私はこれを試して、報告するつもりです。はい、多くのコードとデータが多くのことを望んでいることはわかっています。 –

+0

だから私はこれを試しましたが、今私はビューで問題を抱えています –

+0

ケアを説明する? –

0

Ruby 2.3を使用している場合は、以前の回答から外して、いわゆる孤独な演算子&.を利用することもできます。

例は、次のようになります。kid&.first_name

あなたがこのバージョンのRubyにまだいない場合は、.tryよりやや堅牢なこの状況で助けることができる良いgemがあります。

この宝石を使用すると、コードはkid.andand.first_nameのようになります。この場合、余計になるかもしれませんが、違いはkidがnilでない場合にのみfirst_nameメソッド呼び出しを実行する点です。長いチェーンの場合、parent.address.first.zip_codeの場合、これは、tryで異なる属性をすべて呼び出すのではなく、parentがnilの場合、関数チェーンがすぐに終了することを意味します。

0

条件式以外の条件を使用することはできますか?

unless parent.addresses.first.address_line_1.blank? 
address: parent.addresses.first.address_line_1, 
end 

または

if parent.addresses.first.address_line_1 != nil 
    address: parent.addresses.first.address_line_1, 
else 
address: nil || "address is empty" 
end 
関連する問題