初心者でも分かるRailsで始めるHeroku入門 その2 知って損しないadd onとgem

こんにちは。GMOメディア技術推進室の中村です。最近暑かったり、寒かったりで体調を崩し易い気候ですが、皆様はいかがお過ごしでしょうか?今回は「Heroku/Railsでよく使うgemやadd on」を5つを紹介したいと思います。
- 画像アップロードライブラリpaperclip
- 画像アップロード、変換用クラウドサービスCloudinaryの利用
- リライト用Rackアプリケーションrack-rewrite
- ip制限をかけるrack-contrib
- strong_parameters
1. 画像アップロードライブラリ paperclip
画像アップロードライブラリは幾つかありますが、その中でもよく使うのがpaperclipです。paperclipは実装も簡単でAmazon S3との連携もできます。
今回はAmazon S3と連携する方法を紹介したいと思います。まずGemfileに以下のように追記します。
gem "paperclip", "~> 3.0"
追記したらbundle install
を実行します。
bundle install
次にAmazon S3と連携するためのキーの設定ををします。キーはAmazonの管理コンソールページ ページに書いてあります。
今回は例として画像情報をapp/models/stamp.rb
を使ってデータベースに登録し且つ画像ファイルをS3にアプロードするとします。stamp.rb
に以下のように記述します。
S3_CREDENTIALSでS3の設定情報を記述します。Herokuの環境変数にキー情報を設定した場合は上記のように「ENV」を使って書きますが、それ以外の場合は普通の文字列表記でキー情報を記載します。上記の例ではキー情報を設定した後にhas_attached_file
以下でS3の設定を読み込み、それ以外に画像をアップロードした際に生成するサムネイル画像サイズや画像保存先のパスを定義します。
次にファイル名を変更して画像をアップロードしたい場合のサンプルを示します。以下の例では画像データを格納するStampクラスをapp/models/stamp.rb
とした場合に、そのStampクラスのid属性の値を使ってアップロード画像のアップロード先とファイル名を設定する方法を示します。
paperclip.interpolates :filename
でS3保存時のファイル名(:filename)にPhotoクラスのid属性の値をセットするようにしています。
まずPhotoクラスのデータベースへの登録が終わった後にid属性に値がセットされます。その後に画像をS3にアップロードしますが、その際に上記のように記載することで画像のファイル名をid属性の値に変更してアップロードします。
paperclipを使うと画像を簡単に格納できますが、細かい調整をする場合は、上記のようなModelクラスに処理を追加するなど色々と工夫が必要になります。
2. 画像アップロード、変換用クラウドサービスCloudinaryの利用
弊社では最近画像変換処理でCloudinaryというクラウドサービスを使う事がよくあります。このサービス使うと画像の保存先として使えるだけでなく、画像サイズの変換も手軽にでき非常にオススメです。
ちなみにCloudinaryもAmazon S3を使っているので保存された画像はS3に保存されます。今回ここではHerokuから利用する方法を紹介したいと思います。
まずはpaperclipと同じ画像アップロード用のgemとCloudinary連携用のgemを以下のようにGemfileに追加します。
#cloudinary gem ‘carrierwave’ gem ‘cloudinary’
Cloudinaryではcarrierwaveを推奨しているので、それに従うことにします。carrierwaveは上で紹介したpaperclipと同様によく使われる画像アップロード用のプラグインです。
続いてcarrierwaveを使って画像をアップロードするのに使うModelクラスapp/uploaders/avatar_uploader.rb
を作成します。以下に例を示しますが、詳細は上記のcarrierwaveのgithubページを参考にしてください。
続いてUserクラスapp/model/user.rb
を以下のように編集します。
viewの方では以下のように記述してファイルアップロードのフォームを用意します。
次にファイルのアップロード処理をControllerクラスに以下のように記述します。
@user.avatar=avatar @user.save
後は、RAILS_ROOT/config/cloudinary.yml
に以下のようなCloudinaryとの連携情報を記述すれば設定は完了です。連携情報はHeroku画面でCloudinaryアドオンを選択すると、専用のダッシュボードが表示されそこに記載されています。
これでCloudinaryに画像がアップロードする準備ができました。 CloudinaryはRubyだけでなくJavaやPHPなどからでも使えるので、皆様も是非使ってみてください
3.リライト用Rackアプリケーションrack-rewrite
次に紹介するのがrack-rewriteです。このrack-rewriteはHerokuなどのPaaS環境でApacheのrewrite処理のようなことをする場合に使います。
使うにはまずGemfileに以下のように追記します。
gem ‘rack-rewrite’, ‘~> 1.0.0’
その後にbundle install
実行をします。
続いてconfig/initializers/rack_rewrite.rb
を作成し、このrack_rewrite.rb
の中にrewrite処理を記述します。以下は記述例です。
上の例では本番環境の場合だけ、特定のパスの画像のURLをrewriteでs3上の画像を見るように切り替えています。
4. ip制限をかける rack-contrib
3のrewrite処理の場合と同様にHeroku上で動作するアプリケーションに対してIP制限を掛けたい場合があります。例えば、開発中で一部の人だけがみられるように設定したい場合や別の外部サービスからだけに特定の処理(API)を実行させたい場合などです。その場合はこのrack-contribを使うと良いでしょう。
設定は次のようにします。まずGemfileに以下を追加します。
gem ‘rack-contrib’, ‘1.1.0’, require:‘rack/contrib’
その後にbundle install
実行をします。次にconfig/access.yml
を作成し以下のように記述します。
上記のように記述すると開発環境やテスト環境、本番環境でadmin/user以下の機能へのアクセスを192.168.111.22
からのみに制限し、更に本番環境だけ/admin/point以下の機能へのアクセスを56.2.107.111
からのみ可能にするように制限することができます。
5. strong_parameters
最後にstrong_parametersについて説明します。これはRails4から標準の機能になります。以前githubで指摘され話題にもなりましたが、ActiveRecordのupdateメソッドにはセキュリティ上の問題があります。それはUpdate処理時にRequestパラメータを操作することで意図しない変更処理が実行されてしまうというものでした。現在3.2系ではその対応策としModelクラスがジェネレートされた時にModelクラス内に「attr_accessible」が定義されるようになり、その意図しない更新処理がおきないように修正されました。
Rails4からは、このModelでやっていた更新パラメータチェック(更新項目チェック)をstrong parametersを使ってControllerでやるようになりました。
このstrong parametersを使う場合、更新対象とする項目を以下のようにController内で設定します。
この機能はRails3でも試す事ができますので、早速試してみましょう。まず以下のようにGemfileに追加します。
gem 'strong_parameters'
追加したら、bundle install
を実行します。
実行後、先ほど上で書いたようにController内に以下を追記します。
上記の例ではtitle, description, priority, status
といった項目が更新対象の項目になります。
次にActiveRecordの中を以下のように編集します。
これで準備は終わりです。それではupdate処理で以下のようにupdate_params
を使うように修正してみましょう。
この例ではtitle, description, priority, status
以外の項目を更新しようとしてもupdate_params
メソッドのparams.require(:hoge).permit
メソッドで更新対象から削除されるようになります。こうする事で意図しない項目の更新を防ぐ事ができますが、一方で注意すべきは、もし更新対象が増えた場合には、このメソッドの中身も忘れずに修正しないといけないという点です。
Rails4もそろそろリリースされますからstrong parameterなどRails3でも使える物は早めに使っておくと良いと思います。