【Rails】データを選択して、csv出力する実装から学んだこと


はじめに

こんな感じで検索結果から、任意のデータを選択してcsv出力なんて機能ありますよね。

PFで実装してみようと思うものの、やり方を調べてもなかなかヒットせず。。

そこで!
自分なりにこうしたらいいかな?と考え、実装してみました。

本記事では以下の内容について記載していきます。

  1. どうやって実装方法を考えたか
  2. 処理の流れ
  3. 実装から学んだこと

本記事は初学者による投稿です。
もし、もっとこうした方が良いなどありましたら、コメントいただけると幸いです!!

環境

【OS系】

  • macOS Catalina 10.15.7
  • Ruby on Rails 6.0.0
  • Ruby 2.6.5

【アプリのモデル】

  • matterモデル

案件管理のため、Matterモデルとしています。

どうやって実装方法を考えたか

結論:サーバーサイドから処理を逆算していった

色々試すうちに、まずは任意のレコードを取得する方法が必要だなと考えました。
具体的には以下の流れ考えました。

  1. csv出力するためには、レコードを取得する必要がある。
  2. 意図したレコードはSQLでいうと、どんな文か?
  3. SQL文をrailsのコードに置き換えるとどんなコードか?

処理の流れ

以下の流れで選択したデータがcsv出力されます。

  1. ユーザーにチェックしてもらう。(チェックした時の値は、レコードのIDとなるよう設定)
  2. 出力ボタンをクリックすると、チェックされたレコードのIDが配列となって渡される
  3. IDの配列をもとに、レコードを取得
  4. 取得されたレコードをもとに、csvファイルを作成する

ポイント

チェックボックスで選択した値全てを送るためには、name属性に[]を追加する

チェックボックスにて、選択した値を全て送るためには
name属性に[]を追記する必要があります。

実装中、チェックボックスに入れてるのに、レコードが送られない。。。なんてことがあり
ぼくはこれを知らず、2日くらい溶かしました。

railsのform_withを使って作成したので、コードは以下の感じです。

sample.html.erb
<%= f.check_box "id[]",{class:"checkbox",checked: true},matter.id, false%>

IN句を使ってレコードを取得する

IN句を使うことで、カラムの中から指定された値と一致するものを取得できます。
今回の場合で言うと、IN句でレコードのIDを指定し、レコードを取得しています。

IN句を使用し、SQL文の発行数を一回に抑えました。

railsでIN句を使用するためには、 whereメソッドを使用します。

Matter.where(取得したいカラム:[取得したい値])

実装から学んだこと

やり方を真似るより、完成イメージを考えて実装する方がコードを深く知ることができる

自分の意図した機能は、どういう風に動いていることだろうか?と考えることが重要と思いました。

冒頭にも記述したとおり、ぼくは実装する時やり方を探す癖がありました。

ですが、そうするとコードを深く知ることができていないため
今後改修するときや、人に説明するときに深く話せないなんてこともしばしば。

それでは、今後の役にたたないので、

  1. 完成イメージをする
  2. 逆算して必要なものを考える
  3. サーバーサイドから作っていく

と言う流れが、自分の勉強になり、よいのかなと思っています。

SQL文はなるべく発行数を抑える

エンジニアさんのお話を聞いていると、どうやらSQLを発行する時がシステムに負荷がかかるようです。
そのため、できるだけSQLの発行数を抑える必要があります。

最初はコントローラーに届いたIDの配列を一つずつ取り出し、findで取得と言った感じで実装していました。
コードでいうと以下の感じです。

sample.rb
params[:id].each do |id|
  matter = Matter.find(id)
  ()
end

しかしそうすると、SQL文が届いたIDの数発行されてしまいます。
そこでIN句を使用し、発行数を少なくしています。

sample.rb
(略)
matters = Matter.where(id:params[:id])
()

PFレベルでは問題ないのかもしれませんが、
実務を意識して今後もSQL文は気にしていこうと思っています。(特にORMを使用する時)

参考にした記事

SQLでIN句を使おう!基本からサブクエリ活用方法まで一覧紹介
checkboxの値を複数postする方法
RailsのActiveRecordでwhere in句を使う