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

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

このエントリーをはてなブックマークに追加

こんにちは。GMOメディア技術推進室の中村です。最近暑かったり、寒かったりで体調を崩し易い気候ですが、皆様はいかがお過ごしでしょうか?今回は「Heroku/Railsでよく使うgemやadd on」を5つを紹介したいと思います。

  1. 画像アップロードライブラリpaperclip
  2. 画像アップロード、変換用クラウドサービスCloudinaryの利用
  3. リライト用Rackアプリケーションrack-rewrite
  4. ip制限をかけるrack-contrib
  5. strong_parameters

1. 画像アップロードライブラリ paperclip

画像アップロードライブラリは幾つかありますが、その中でもよく使うのがpaperclipです。paperclipは実装も簡単でAmazon S3との連携もできます。

thoughtbot/paperclip · GitHub

今回はAmazon S3と連携する方法を紹介したいと思います。まずGemfileに以下のように追記します。

gem "paperclip", "~> 3.0"

追記したらbundle installを実行します。

bundle install

次にAmazon S3と連携するためのキーの設定ををします。キーはAmazonの管理コンソールページ ページに書いてあります。

image

今回は例として画像情報をapp/models/stamp.rbを使ってデータベースに登録し且つ画像ファイルをS3にアプロードするとします。stamp.rbに以下のように記述します。

https://gist.github.com/nakaearth/5097145

S3_CREDENTIALSでS3の設定情報を記述します。Herokuの環境変数にキー情報を設定した場合は上記のように「ENV」を使って書きますが、それ以外の場合は普通の文字列表記でキー情報を記載します。上記の例ではキー情報を設定した後にhas_attached_file以下でS3の設定を読み込み、それ以外に画像をアップロードした際に生成するサムネイル画像サイズや画像保存先のパスを定義します。

次にファイル名を変更して画像をアップロードしたい場合のサンプルを示します。以下の例では画像データを格納するStampクラスをapp/models/stamp.rbとした場合に、そのStampクラスのid属性の値を使ってアップロード画像のアップロード先とファイル名を設定する方法を示します。

https://gist.github.com/nakaearth/5097524

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と同様によく使われる画像アップロード用のプラグインです。

jnicklas/carrierwave · GitHub

続いてcarrierwaveを使って画像をアップロードするのに使うModelクラスapp/uploaders/avatar_uploader.rbを作成します。以下に例を示しますが、詳細は上記のcarrierwaveのgithubページを参考にしてください。

続いてUserクラスapp/model/user.rbを以下のように編集します。

https://gist.github.com/nakaearth/8eda1f3fd063f654b833

viewの方では以下のように記述してファイルアップロードのフォームを用意します。

https://gist.github.com/nakaearth/63a22c4e66240edb0a44

次にファイルのアップロード処理をControllerクラスに以下のように記述します。

@user.avatar=avatar
@user.save

後は、RAILS_ROOT/config/cloudinary.ymlに以下のようなCloudinaryとの連携情報を記述すれば設定は完了です。連携情報はHeroku画面でCloudinaryアドオンを選択すると、専用のダッシュボードが表示されそこに記載されています。

https://gist.github.com/nakaearth/ec5d4d5f0b62d2ecffff

これで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処理を記述します。以下は記述例です。

https://gist.github.com/nakaearth/bdb970fd2d0a213c08da

上の例では本番環境の場合だけ、特定のパスの画像の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を作成し以下のように記述します。

https://gist.github.com/nakaearth/5192786

上記のように記述すると開発環境やテスト環境、本番環境で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内で設定します。

https://gist.github.com/nakaearth/1ce5bd1925331e017e31

この機能はRails3でも試す事ができますので、早速試してみましょう。まず以下のようにGemfileに追加します。

gem 'strong_parameters'

追加したら、bundle installを実行します。

実行後、先ほど上で書いたようにController内に以下を追記します。

https://gist.github.com/nakaearth/5192827

上記の例ではtitle, description, priority, statusといった項目が更新対象の項目になります。

次にActiveRecordの中を以下のように編集します。

https://gist.github.com/nakaearth/358942050dc2dee0013e

これで準備は終わりです。それではupdate処理で以下のようにupdate_paramsを使うように修正してみましょう。

https://gist.github.com/nakaearth/1e40c2ce231ccd403e1d

この例ではtitle, description, priority, status以外の項目を更新しようとしてもupdate_paramsメソッドのparams.require(:hoge).permitメソッドで更新対象から削除されるようになります。こうする事で意図しない項目の更新を防ぐ事ができますが、一方で注意すべきは、もし更新対象が増えた場合には、このメソッドの中身も忘れずに修正しないといけないという点です。

Rails4もそろそろリリースされますからstrong parameterなどRails3でも使える物は早めに使っておくと良いと思います。


名無しのエンジニア
Railsの自動テスト(RSpecでModelのテスト編)
mroongaをXtraDB Clusterで冗長化できそうなメモ