Ruby on Rails開発のインターン (Day 34)

こんにちは、皆さん!

今日は僕のマネージャーがデータをインポートしようとしたときに生じたエラーの解決を主にやっていこうと思う。僕の書いたマップのテストコードがまだ半分完成というもうちょっと大きな問題もあるが、マップができてないし、今週で僕のインターンは終了なので、おそらくこの状態で渡すことになる。マネージャーたちにあとは任せるしかないね。


  • トピック:
  1. Railsでcsvファイルを作る
  2. send_dataという関数でユーザーのファイルダウンロードを実装する
  3. %w{}で文字列の配列を作る


  • 疑問:
  1. なぜ、send_dataが描画 (render) 関数に分類されるにもかかわらず、それを使った後に、flash.nowがうまく作用しないのか?


  • 問題:


  • 学習した内容:


  • 今後やってみたいこと:


  • リソース:
  1. Export Records to CSV Files with Rails | Codementor
  2. ruby on rails - How to generate a CSV file in action? - Stack Overflow


Railscsvファイルを作る

これはデータを決まったフォームでエクスポートできるという非常に優れた機能である。僕はただこのStackOverflow(
https://stackoverflow.com/questions/31762865/how-to-generate-a-csv-file-in-action)に記されていた通りにやっただけなのでとても簡単。これに記されている通り、to_csvという関数をモデルファイルの中に作り、下記の内容を入れる(関数の最後の部分が以下のように出来上がったcsvを返す内容なら問題ないはず)。

    CSV.generate(headers: true) do |csv|
      csv << attributes

      cars.each do |car|
        csv << attributes.map{ |attr| car.send(attr) }
      end
    end

よって、僕は自分のを下記のように作った

  def to_csv(error_lines)
    attributes = # can't show you this
    CSV.generate(headers: true) do |csv|
      csv << attributes

      error_lines.each do |hash|
        csv << hash
      end
    end
  end

というわけで、これがto_csv関数を自分の思うようにカスタマイズする方法だ。

最後に、僕は下記のコードでcsvファイルを返してくれるウェブ上での操作を実装した。

      send_data to_csv(error_lines), filename: "error_lines.csv"

ん?send_dataって何?ってなるのでsend_dataについて次のセクションでもっと詳しく解説していこうと思う。

send_dataという関数でユーザーのファイルダウンロードを実装する

send_data関数は直接ユーザーにファイルをダウンロードさせるものだ。よくウェブサイトでダウンロードというリンクを押すと、新しいタブが開かれて、ダウンロードが始まるかと思う。まさにあれなんです、これがやっているのは!

しかしながら、この関数を使ってみたところ、少々面倒くさいものがいくつか見つかった。この関数のもっとも厄介なところは描画 (render) 関数であること。これが意味するところは、この関数をコントローラー内で使用することで同じアクション内ではリダイレクトなどの操作ができなくなることだ。
下記のコードはこのサイトで見つけたsend_data関数のソースコード

# File actionpack/lib/action_controller/metal/streaming.rb, line 112
      def send_data(data, options = {}) #:doc:
        send_file_headers! options.dup
        render options.slice(:status, :content_type).merge(:text => data)
      end

見ての通り、render関数を実行している。
でも、なぜなのか僕のflash.nowはここでは正常に機能しなかった。(いまだに未解決)

%w{}で文字列の配列を作る

ここの内容はcsvファイルから少し離れるが、今回csvファイルの操作を学習する中で触れる機会があったので、ついでにここにメモしておこうと思う。

使用頻度は高くないかもしれないが、一つ一つの要素の間にコンマを入れる必要がないので、文字列の配列を定義する速度をすごく高めてくれる。

この関数を使用する方法は下記のような感じだ:

# same as array = ["name", "age", "gender", "email"]
array = %w{name age gender email}

そう、つまり、一つ一つの要素をコンマの代わりにスペースで仕分ける。おまけにクオーテーションもいらないという。意外と慣れないと癖でクオーテーションを打ってしまうのが個人的な感想かな(笑)

もし、スペースを含んだ文字列を入れたいのなら?

下記のようにやりましょう!

# same as array = ["date of birth", "my goal"]
array = %w{date\ of\ birth my\ goal}

とてもシンプル。ただ\を入れて、スペースをエスケープするだけ。

まとめ

今日はとてもたくさんRuby独特のコードについて学ばされた一日だった。こういう新しいことをやるたびに、Rubyって本当に様々な機能があって、いつまで経ってもすべてをカバーできないような気がしてくる(笑)
明日は引き続きインポート機能をやり、更に、もう2日しかないので、残りの諸事情が無事に片付くことを願いたい。


ご精読ありがとうございました。では、また次回まで✌



Day 35はこちら↓↓
programming-shop.hatenablog.com


Day 33はこちら↓↓
programming-shop.hatenablog.com