Ruby on Rails開発のインターン (Day 34)
こんにちは、皆さん!
今日は僕のマネージャーがデータをインポートしようとしたときに生じたエラーの解決を主にやっていこうと思う。僕の書いたマップのテストコードがまだ半分完成というもうちょっと大きな問題もあるが、マップができてないし、今週で僕のインターンは終了なので、おそらくこの状態で渡すことになる。マネージャーたちにあとは任せるしかないね。
- トピック:
- 疑問:
- なぜ、
send_data
が描画 (render) 関数に分類されるにもかかわらず、それを使った後に、flash.now
がうまく作用しないのか?
- 問題:
- 学習した内容:
- 今後やってみたいこと:
- リソース:
- Export Records to CSV Files with Rails | Codementor
- ruby on rails - How to generate a CSV file in action? - Stack Overflow
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{}
で文字列の配列を作る
使用頻度は高くないかもしれないが、一つ一つの要素の間にコンマを入れる必要がないので、文字列の配列を定義する速度をすごく高めてくれる。
この関数を使用する方法は下記のような感じだ:
# 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}
とてもシンプル。ただ\
を入れて、スペースをエスケープするだけ。
まとめ
明日は引き続きインポート機能をやり、更に、もう2日しかないので、残りの諸事情が無事に片付くことを願いたい。
ご精読ありがとうございました。では、また次回まで✌