【Rails】MySQLを動かす、queryとprepareメソッドの使い方

2018年3月9日

RubyでMySQLを動かすための手段、メソッドをメモしておく。

WEBサーバー(Puma)をいつものように起動しておく

ターミナルからPumaとSinatraを起動しておく。

$ruby aiueo.rb -o $IP -p $PORT

WEBアプリのフォルダ構成はいつものように以下のようになっている。

aiueo.rb
viewフォルダ
└ index.erb

Rubyでデータベースを使うのは決まり文句で覚えておこう

まず最初に、いつものようにAWS Cloud9上にてプログラミングを行うので、AWS Cloud9でRubyとMySQLを連携するためのmysql2というGEMをインストールしておく。

ターミナル上でのコマンドはこれを打ち込む。

$ sudo yum install mysql-devel -y
$ gem install mysql2
require 'mysql2'

で読み込んでおく。

Mysql2のClientクラスをインスタンスで生成する。

aiueo = Mysql2::Client.new(host: 'localhost', username: 'root', database: 'データベース名', encoding: 'utf8')

セレクト文の書き方はこのようにquery()メソッドで発行する

@records = aiueo.query("SELECT * FROM テーブル名 ORDER BY created_at DESC")

戻り値は、@~~ を宣言して入れることが慣例になる。

@~~で宣言したインスタンス変数(この場合@records)は、Sinatraの機能によってERB側でも@~~で使用できるようになる。

ここは@必須なので覚えておくことォ!

@recordsを表示してみると、

#<Mysql2::Result:0x00000001c71f90>

が表示される。ここはオブジェクトの番号なんかが見えるだけ。

@records.each do |record|

で、1行ずつ取り出してみると、セレクト文で取り出したデータがハッシュで入っている。
なのでrecord[カラム名]とやると、中身が取り出せる。

インサート文の書き方はprepare()メソッドを使う事が慣例になっている

aiueo = Mysql2::Client.new(host: 'localhost', username: 'root', database: 'データベース名', encoding: 'utf8')
statement = aiueo.prepare('INSERT INTO テーブル名 (カラム名) VALUES(?)')

prepare()メソッドのリファレンスを確認中。見つからない。

HTMLのフォームにユーザーがSQL文を流した時、それをそのままINSERTするとマズイのでワンクッションを置くセキュリティを考慮した書き方。

例えば;で無理やり区切って、DBの中のユーザー情報をSELECTするようなSQLを流してくるかもしれないし、ということ。

引き続き?に入る値を

statement.execute(値)

とやって、このメソッドでインサート文が流れる。

もし値を2つ入れるような場合は

statement = aiueo.prepare('INSERT INTO テーブル名 (カラム名1,カラム名2) VALUES(?,?)')
statement.execute(値1,値2)

これでOK

HTML側に表示する際のセキュリティ対策

HTML側に表示する際にユーザーがフォームから入力した物をDBに入れ出しするような処理は注意が必要。
クロスサイトスクリプティングの脆弱性に対処する必要があり、そのためのメソッドがあるので使うこと。

<%= ERB::Util.html_escape(ここに値) %>

こうすると、例えばJavascriptのような<script>がユーザーに埋め込まれても、&lt;と、&gt;に変換してくれる。
ブラウザがスクリプトタグとして認識するのではなく文字として認識してくれるようになるので、これは必ずやらないといけない。

そういえば、昔10年以上も前にやったような記憶があるわ。
昔は自前で関数を作って対処してたきがする。今はセキュリティ用のメソッドがあるんだね。