Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
4
Help us understand the problem. What is going on with this article?
@nyappy15th

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

はじめに

こんな感じで検索結果から、任意のデータを選択してcsv出力なんて機能ありますよね。
選択結果を出力.gif
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句を使う

4
Help us understand the problem. What is going on with this article?
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
nyappy15th
4月より、未経験から受託開発企業のフロントエンドエンジニアとして働いてます。 Vue / bootstrap /Javascript / RubyOnRails / SQL

Comments

No comments
Sign up for free and join this conversation.
Sign Up
If you already have a Qiita account Login
4
Help us understand the problem. What is going on with this article?