Node.js 環境変数の設定

こんにちは、皆さん!
今回はNode.jsで安全に環境変数を設定する方法について紹介していきたいと思います。


  • トピック:
  1. 環境変数とは?
  2. なぜ環境変数を使うのか?
  3. なぜ環境変数を安全に保護しないといけないのか?
  4. どうやって安全にキープするのか?
  5. では、試してみましょう!!


環境変数とは?

***環境変数の基本を飛ばしたい方はこちら!***
簡単に言いますと、外部から与えられるデータのことです。直接コードの中ではそのものを書かずに他のファイルからそれを読み取ります。


なぜ環境変数を使うのか?

Google Mapをアプリケーションに応用しようと思ったときにAPIというものが必要になってきます。相手側のサービスを利用するにあたっての個人のIDみたいなものです。権利書みたいでもあり、そのAPIがないと利用できません。

なぜ環境変数を安全に保護しないといけないのか?

ウェブ上のコードというのはとても簡単に他人に見られます。先ほどのAPIというのはいうと、数字とアルファベットの羅列です。だから、見られたらそのまま盗まれます。そして、あなたの名義でその権利書を使い、その人のアプリケーションを作る。料金のかかるAPIですと、他人のために金を払うことになります。だから、環境変数にその危ない部分を移し、なおかつその環境変数を含んだファイルを見られないようにすることが大事なのです。


どうやって安全にキープするのか?

まず、Node.jsでは下記のように環境変数にアクセスできます。

process.env.API_KEY

envの後に環境変数の名前をつければアクセスできます。
ローカルでは他のファイルに保存しておけば、アクセスできます。このファイルに関してはgitignoreしっかりとオンラインにシェアされないように
プロダクション、つまり、オンラインでは例えば、Herokuならconfig環境変数を保存すれば他人には見られないので安全にキープできます。

では、試してみましょう!!

僕のコードをhttps://github.com/Eric1015/node-environment-variables-exampleに載せておきましたので、参考にしてください。
おススメはそのコードをダウンロードして、この記事通りに見て、そして、ローカルやHerokuで試してみることです。
まず、コードの構造について少し説明します。configディレクトリーの中にあるのが環境変数を管理する部分です。
prod.jsがプロダクション、test.jsがテスト、dev.jsがローカルという形でそれぞれがそれぞれの環境の変数を管理しています。
次にindex.jsファイルで環境に応じてどのファイルのデータを返すかを決めます。

if (process.env.NODE_ENV === 'production') {
    module.exports = require('./prod');
} else if (process.env.NODE_ENV === 'test') {
    module.exports = require('./test');
} else {
    module.exports = require('./dev');
}

ここにあるように環境ごとにそれぞれの変数を管理しているファイルを返すのです。
あとは.gitignoreの方でローカルとテスト環境の変数が外部に漏れないようにフィルターするだけ

# モジュールはわざわざプッシュする必要はない
node_modules

# ローカルとテスト環境の環境変数はGithubに表示されないようにします
config/dev.js
config/test.js



以上で環境変数の設定は完了。そしたら、server.jsで実際にどう使うかを見てみましょう!
ここではMongooseを使う際のURLを環境変数を使い、各環境で違うデータベースにアクセスできるようにします。
まず、ローカルとテスト環境のデータベースのURLを設定します。

// dev.js
module.exports = {
    DB_URI: "mongodb://localhost:27017/environment-variables-app"
}
//test.js
module.exports = {
    DB_URI: "mongodb://localhost:27017/environment-variables-app-test"
}

次にプロダクションの方の変数も定義したいのですが、プロダクションではサーバー側の設定から環境変数がパスされてきます。例えば、Herokuでこのアプリケーションを使うのなら、そこで、変数の名前をDB_URIとし、実際のURLを入れ、下記のようにその変数にアクセスします。

// prod.js
module.exports = {
    DB_URI: process.env.DB_URI
}

これならGithubに載せても他人から情報を盗まれませんね!
では、いよいよserver.js内のコードを見ていきましょう!
まず、外部から必要なものをインポートしてきます。このとき、require('./config')となっていてディレクトリーをインポートしようとしているように見えるが、実はindex.jsを認識して、そこにたどり着いているのです。
次にconst url = config.DB_URI;環境変数にアクセスし、MongoDBのURLを取得します。
そして、最後にサーバーをスタートします。

const express = require('express');
const mongoose = require('mongoose');
const config = require('./config');

const url = config.DB_URI;
const port = process.env.PORT || 8080;

// MongoDBデータベースに接続
mongoose.connect(url, function (err, res) {
    if (err) { 
      console.log ('ERROR connecting to: ' + url + '. ' + err);
    } else {
      console.log ('Succeeded connected to: ' + url);
    }
});

// サーバーをスタートする
const app = express();

app.get('/', (req, res) => res.send('Hello World!'))

app.listen(port, () => console.log(`Example app listening on port ${port}!`))



実際にこのサーバーをスタートすれば、コンソールで実際にどのMongoDBのサーバーに接続したかが見れます。


では、次はHerokuでどうやって設定するかです。
まずはHerokuのconfigを確認してみましょう!

$ heroku config

すると、まだ何も入れてないので、空の状態です。
HerokuでMongoDBを使おうとすると、mLabというアドオンを入れる必要があるので、それを入れてみましょう!

f:id:Programming_Shop:20190318080104p:plain
mLabのコンソール画面(左上のロゴを参照に)


追加した後にもう一度heroku configとやると、今足したmLabのURLが見れるはずです。

MONGODB_URI: mongodb://heroku_3636wvfr:ka9cqpra6f4r8g3gfk8n2la4bs@ds255797.mlab.com:55797/heroku_3636wvfr

こんな感じで出てくるのだが、今のアプリではDB_URIという環境変数でアクセスしているので、環境変数をこの名前で新たに追加しましょう!!
下記のコマンドを入力して、configに環境変数を追加しましょう!

$ heroku config:set DB_URI=mongodb://heroku_3636wvfr:ka9cqpra6f4r8g3gfk8n2la4bs@ds255797.mlab.com:55797/heroku_3636wvfr

後ろの部分はご自身のMongoDBのURLを入れてくださいね!
ここで、またコマンドでconfigを開くと、

DB_URI:           mongodb://heroku_3636wvfr:ka9cqpra6f4r8g3gfk8n2la4bs@ds255797.mlab.com:55797/heroku_3636wvfr

この内容が追加されています。
これでHerokuのサイト上でもアクセスできるようになります!!


まとめ

今回は環境変数を有効かつ安全に使う方法について見てきました。
僕もはじめはこんなに簡単に設定できるのかと感心しました。
みなさんの役に立つことを願います!
では、また次回まで✌
記事更新はツイッターで告知するので、ツイッターの方でもフォローお願いします!
twitter.com



最新版 2019年にプログラミング始めるならJavaScript↓↓
programming-shop.hatenablog.com


RspecでJSONオブジェクトの値を確認する

こんにちは、皆さん!

Railsウェブアプリケーションを作っていく上で、その品質を保証するためにRspecは欠かせない。そして、最近ではRailsAPIを作る人たちも増えてきている。そんなAPIなのだが、普通コントローラーがJSONオブジェクトという形でデータを返してくる。今回はそのオブジェクト内の値をチェックする方法を紹介したいと思う。


  • トピック:
  1. 今回使うモデルの説明
  2. うまくいかない例
  3. うまくいく例


今回使うモデルの説明

今回はUserモデルを使い、メール、パスワード、確認パスワードの3つを使ってユーザーを作成(つまり、POSTリクエスト)、そして、そのアクションで作られたユーザーをJSONオブジェクトとして返すという形をとる。下記がUserコントローラーのcreateアクション。

    # users_controller.rb
    def create
        @user = User.create(user_params)
         render json: @user, status: :created
    end

    private

    def user_params
        params.require(:user).permit(:email, :password, :password_confirmation)
    end

ベースのテストコードは下記のようになっている。今回はここにもう一つコードを足して、JSONとして返ってきたオブジェクトのメールがもともと入れたメールと同じか確認する。

    # users_controller_spec.rb
    describe "POST create" do
        it "should create a user with valid params" do
            post :create, params: {user: {email: "example@example.com", password: "foobar", password_confirmation: "foobar"}}
            expect(response).to have_http_status(:created)
        end
    end

覚えておくべきことは

  • ここで使うのはcreateアクションだけであること
  • そのアクションではJSONオブジェクトのUserが返され、:createdというステータスがついてくること
  • そのステータスはテストコードのPOSTリクエスト後に確認がされていること
  • response.bodyに返されたJSONオブジェクトの詳細が入っていること

では、実際に両方の例を見ていこう!!

うまくいかない例

まずよくやっちゃううまくいかない例。僕もこれをよくやりがちなのだが、JSONオブジェクトだからといって下記のようにそのままキーを使って値を取り出そうとするパターン。

    describe "POST create" do
        it "should create a user with valid params" do
            post :create, params: {user: {email: "example@example.com", password: "foobar", password_confirmation: "foobar"}}
            expect(response).to have_http_status(:created)
            expect(response.body['email']).to eq("example@example.com")
        end
    end

これはいつもJavaScriptでキーを使って値を抜き出してる人からしたら、とても常識的なやり方。しかし、Rubyでは下記のように想定外のことがおこり、テストが下記のようにフェイルしてしまう。

  1) V1::UsersController POST create should create a user with valid params
     Failure/Error: expect(response.body['email']).to eq("example@example.com")

       expected: "example@example.com"
            got: "email"

       (compared using ==)
     # ./spec/controllers/users_controller_spec.rb:16:in `block (3 levels) in <top (required)>'

これはつまり何かというと、response.body['email']の結果がemailになっているのだ。
試しにputs response.bodyresponse.bodyの内容をアウトプットしてみた。そしたら下記の結果が得られた。

{"id":841425152,"email":"example@example.com","created_at":"2018-12-30T19:26:45.289Z","updated_at":"2018-12-30T19:26:45.289Z"}

これって当たり前だけど、JavaScriptのキーと値のペア式になっているのだ。でも、これこそが問題の原因。なぜなら、Rubyでのキーと値のペア式はJavaScriptのそれとは違うからだ。皆さんもご存知かと思うが、下記のようなシンタックスRubyのやり方。

{"id"=>841425155, "email"=>"example@example.com", "created_at"=>"2018-12-30T23:07:17.457Z", "updated_at"=>"2018-12-30T23:07:17.457Z"}

そう、=>のような矢印でシンボルを表現するやり方だ。では、次にどうやったらRubyのわかる形に変更できるかについて見ていこう!!

うまくいく例

では、いったいどうやってRuby式のキーと値ペアにするのかというと、この関数を使うのだ。

JSON.parsse()

これは単純にJSONオブジェクトをRubyのわかるものに変えるだけなのだ。言うなら、to_json()関数の逆をやっているのだ。
よって、先ほど、puts response.bodyJavaScriptの形になっていたものはputs JSON.parse(response.body)と改めることで下記のようになる。

{"id"=>841425155, "email"=>"example@example.com", "created_at"=>"2018-12-30T23:07:17.457Z", "updated_at"=>"2018-12-30T23:07:17.457Z"}

つまり、うまくいくRspecのコードは下記のようになる。

    describe "POST create" do
        it "should create a user with valid params" do
            post :create, params: {user: {email: "example@example.com", password: "foobar", password_confirmation: "foobar"}}
            expect(response).to have_http_status(:created)
            expect(JSON.parse(response.body)['email']).to eq("example@example.com")
        end
    end


まとめ

どうだったでしょうか?
このように問題を発見することができれば、あとはしっかりとしたRubyの知識があればこのような問題は解決できる。なので、何かエラーに面したときはいろいろとプリントアウトしてみて、手掛かりを探しましょう!!
皆さんのテストコードがより素晴らしいものになることを祈ります。


ご精読ありがとうございました。では、また次回まで✌



Herokuのステージングブランチとは?(導入編)↓↓
programming-shop.hatenablog.com

Herokuのステージングブランチとは?(実践編)

こんにちは、皆さん!

ここではどうやってHerokuでステージングブランチを作れるのか、そして、そこで役に立つちょっとした予備知識と一緒にお伝えしようと思う。Herokuのステージングブランチについての解説はこちらの導入編を参照してください。→
Herokuのステージングブランチとは? (導入編) - Programming_Shopの日記


  • トピック:
  1. ステージングブランチの作り方
  2. プロダクションのコードを更新する
  3. ステージングブランチにプッシュ先を変更する
  4. ステージングブランチの注意点
  5. Herokuのメンテナンスモード
  6. おまけ


ステージングブランチの作り方

では、さっそく最初のステージングブランチを作っていきましょう。
まず、Herokuアカウントを開いて、そして、ステージングブランチにしたいアプリを選びます。ここでは、僕自身のHerokuで例を挙げていく。下記のようにHerokuのアプリケーションがいくつかある。ここでthis-will-be-stagingをステージングブランチにするとしよう。なので、まずそのアプリケーションの詳細に入る。
f:id:Programming_Shop:20181210112059p:plain
ホーム画面からアプリへ


その後、ダッシュボードからDeployをクリック。
f:id:Programming_Shop:20181210112449p:plain
ダッシュボードからDeploy


そしたら、パイプラインを作成するので、Choose a pipelineからCreate new pipelineを選択。
***注意***
ここで、本家の方に選ぶHerokuのアプリ内のコードはステージングブランチに選んだコードに変更されるので、くれぐれも失いたくないコードの入ったHerokuアプリを本家として選ばないでください!!

f:id:Programming_Shop:20181210113210p:plain
新しいパイプラインを作成する


このパイプラインというのはつまりは2つのHerokuのアプリケーションをつなげるようなものである。そしたら、いつでもステージングブランチのコードを本家の方にプッシュすることができるのだ。
名前を付けてパイプラインの作成は完了。ここでは、heroku-staging-testという名前にした。

そしたら、おそらくこんな感じの画面になったでしょう。まだステージングブランチだけで本家がないので、ここで追加していく。Add appをクリック。

f:id:Programming_Shop:20181210115121p:plain
本家を追加するための画面


ここで、今回は最初にホームページで見せたthis-will-be-productionが本家なのでサーチバーからタイプして選択した。そしたら、下記のようにパイプラインが完成。
f:id:Programming_Shop:20181210115256p:plain
パイプライン完成!


次はステージングブランチのコードを本家にプッシュして本家のウェブサイトのコードを更新していく。

プロダクションのコードを更新する

ここまででとりあえず、ステージングブランチと本家の間にパイプラインを作ることに成功した。ここからは実際に運用していくステージで、ステージングブランチにいれた新しいコードを本家にプッシュして、反映させる。
f:id:Programming_Shop:20181210115329p:plain
ステージングブランチから本家にプッシュ
この赤丸を打ったボタンがまさしくこれまでいつでもステージングブランチのコードを本家にプッシュすることができるといっていたボタンなのだ。


ここで、Promoteというボタンをおして、プッシュを完了すると、下記のような画面になる。
f:id:Programming_Shop:20181210115512p:plain
プッシュ完了!


これはただいまステージングブランチと本家のコードはまったく同じであるということを言っているのだ。そして、以降ステージングブランチのコードを変えるたびにこのボタンが先ほどのボタンのようになり、またプッシュすることができるようになる。


こうしてパイプラインのセットアップが完了した後にホームページに戻ると、下記のように先ほどの2つのアプリが1つにまとまっているでしょう。
f:id:Programming_Shop:20181212032205p:plain
パイプライン完了後のホームページ

ステージングブランチにプッシュ先を変更する

ステージングブランチの作り方とウェブサイトのコードをステージングブランチから更新する方法について話してきた。しかし、どうやったらステージングブランチのコードを更新できるのか?
これについて話す前に、まず注意したいのはステージングブランチはステージングブランチという特別な名前を与えられているが、結局は1つのHerokuのアプリケーションであることを肝に銘じてもらいたい。なので、いつもHerokuにプッシュするようにステージングブランチに更新したコードをプッシュすることができるのだ。


ここで、今エディターで編集しているコードのプッシュしている先がステージングブランチになっていない場合は下記のようにプッシュ先を設定しましょう。
まず、Herokuのページからまずステージングブランチのアドレスをコピーします。ステージングブランチのアプリを開いて、Settingsをクリック。ちょっとスクロールしたところに下記のようなものがあるので、この赤丸のところをコピー。
f:id:Programming_Shop:20181212040637p:plain
ステージングアプリのアドレスをコピー


その後、編集しているコードのディレクトリーをターミナルで開いて、下記のようにHerokuへのプッシュ先を設定する。
(heroku addressの部分に先ほどのコピーしたアドレス。<>は不要)

git remote add heroku <heroku address>

こうすれば、今後Herokuにプッシュする際にはステージングブランチの方にコードが行くようになる。

ステージングブランチの注意点

ステージングブランチを使っていく上で、いくつか覚えていただきたい注意点がある。

  • ステージングブランチと本家ではデータベースが別々である

ここでもう一度おさらいするが、ステージングブランチもまた1つのHerokuアプリであるので、それ自身にデータベースも存在し、これは本家の方と別のものである。なので、ステージングブランチで新たに足したデータは本家には反映されないし、逆に本家で追加したデータもまたステージングブランチには反映されない。
しかし、これがまたステージングブランチのいいところで、ステージングブランチで様々なデータをテストする際にそれが本家に影響を与えるかどうか気にしなくていいということである。

  • 必要なアドオンを再追加する

これまたアプリが分かれているためだが、本家で使われているHerokuのアドオンでテスト時に必要になるアドオンはステージングブランチにもしっかり追加しよう。例えば、メール送信をテストしたいのなら、sendGridを追加する。

こちらもまた本家と同じように追加しないと、アプリがうまく動作しないかもしれないのであるのなら追加しましょう。また、その変数の使い方によるが、テストするために本家とは違うテスト用の変数を設定してもよいでしょう。

Herokuのメンテナンスモード

最後に、ステージングブランチのコードを本家にプッシュする際にとても役に立つメンテナンスモードについて説明していこうと思う。
実は、Herokuにはメンテナンスモードがあり、いつでもユーザーがその状態を変更できる。もしも、メンテナンスモードになっている状態で、そのウェブサイトに行くと、下記のようにウェブサイトのコンテンツを見ることができないようになっているのだ。
f:id:Programming_Shop:20181212043746p:plain
Herokuのメンテナンスモード


これがなぜ役に立つのかというと、ステージングブランチのコードを本家にプッシュする際に、Herokuは一度、アプリを止めるので、ユーザーの邪魔をしてしまうのだ。特にアクセスが集中している本家のサイトだと多くのユーザーに影響を与えやすい。なので、一度本家をメンテナンスモードにして、ユーザーのアクセスを無効にして、変にユーザーのデータ更新を邪魔しないようにするのだ。
これもまた簡単で、本家の方のアプリのSettingsに行って、下記の画面までスクロール。
f:id:Programming_Shop:20181212044435p:plain
メンテナンスモード変更のボタン


このボタンでメンテナンスモードをオンにしたり、オフにできる。また、もし、本家の方のアドレスをいれたディレクトリーがあるのなら、下記のようにターミナルからでも設定できる。1つ目でメンテナンスモードにし、2つ目でメンテナンスモード解除。

heroku maintenance:on
heroku maintenance:off



1つだけ注意したいのは、ステージングブランチをメンテナンスモードにしても意味ないので、先ほどアドレスを設定したステージングブランチではなく、本家でこのコマンドを使うことを覚えておこう。

おまけ

Herokuはデフォルトでアカウント1つにつき5個までしかアプリを持つことができない。この条件で行くと、ステージングブランチとか作ると、すぐに2個分のアプリのスペースを取ってしまう。なので、できれば、クレジットカードを登録しよう。登録するだけなら、何もお金を払うことはない上、さらに、持てるアプリの数が一気に200個まで増加するので、オススメ!

まとめ

以上で、Herokuでのステージングブランチの使い方の説明になる。Herokuを使って、アクセスの多い大きなウェブサイトを管理していく上で、何段階にもなるテストはサービスの質を確証する上で、大事になってくる。その際に、ステージングブランチはユーザーに影響を与えずにHeroku上でのテストを可能にしてくれるとても便利な機能である。みんなもぜひステージングブランチを有効活用して、さらなるウェブサービスの向上に精進してください。


ご精読ありがとうございました。では、また次回まで✌



Herokuのステージングブランチとは?(導入編)↓↓
programming-shop.hatenablog.com

Herokuのステージングブランチとは?(導入編)

こんにちは、皆さん!

ステージングブランチというものをみなさんもどこかで一度は聞いたことがあるかもしれない。特にすでに会社でHerokuを使っているという場合はなおさらである。今回はWeb開発を効率化し、そして、メインテナンスをより簡単にさせてくれるステージングブランチについて紹介していきます。(実践編はこちら→
Herokuのステージングブランチとは?(実践編) - Programming_Shopの日記


  • トピック:
  1. ステージングブランチとは?
  2. ステージングブランチの利点


  • リソース:
  1. Managing Multiple Environments for an App | Heroku Dev Center


ステージングブランチとは?

***注意***
以下の内容を理解するにはGitの知識が少し必要になってきます!

まず、初めにステージングブランチとは何かについて説明していこうと思う。ざっくり簡単に言うと、GitのマスターブランチがHerokuにデプロイしたコードでステージングブランチはGitのマスターブランチ以外のブランチといえる。つまり、実際に運営しているウェブサイトとは別にもう一つ同じ内容のウェブサイトを持つことができるということだ。
もっと一般的な例でいうのなら、劇を例に挙げて、ローカルでのテストが練習、ステージングブランチでのテストがリハーサル、そして、本家のウェブサイトにデプロイが本番といったような感じだ。(以下の図参照)

f:id:Programming_Shop:20181209092651p:plain
劇とウェブサイト構築の対称
そして、Gitでマージするように、このステージングブランチのコードはいつでも本家の方のウェブサイトにプッシュすることができるのだ。

ステージングブランチの利点

では、本題ですね。いったいなぜステージングブランチを使う必要があるのか?
大きく分けてステージングブランチを使うことには2つの利点があります。

  • Herokuにデプロイした際、エラーがあっても、ユーザーに影響を与えない

Herokuとローカルでテストしたときに内容が違うことはよくある。例えば、レイアウトのサイズ感が少し違う(これに関してはどうしてなっちゃのかいまだに謎)など。これをユーザーが直接見る本家のウェブサイトにデプロイしないで、ステージングブランチにデプロイすることで、事前確認ができ、修正することができる。

  • Herokuでしかテストできない要素がある

少し1個目とも被るが、例えば、メールをユーザーに送信するものなどは確かにローカルでテストコードを書いてテストしてみることもできるが、やはり、最終的にはHerokuにデプロイした後の状態で確認する必要がある。この時、本家に直接デプロイすると、ユーザーもその新しいエラーのあるかもしれない機能に触れる可能性があり、非常に望ましくない。なので、まずはステージングで確認するところから始める。

これらを踏まえると、下記のような仕事の流れができる。

f:id:Programming_Shop:20181209093901p:plain
ステージングブランチと仕事の流れ
このようにプログラマーはローカルとステージングの間を行き来し、最終的に完全なものだけをユーザーに届けるのというシステムになっているのだ。

まとめ

導入編はここまで。次は実践編で実際にどうやったらHerokuでステージングブランチを実行することができるのかを紹介していきます。実際に自分のアプリケーションに取り入れたい人はぜひ下記のリンクからどうぞ↓↓
Herokuのステージングブランチとは?(実践編) - Programming_Shopの日記


ご精読ありがとうございました。では、また次回まで✌



Herokuのステージングブランチとは?(実践編)↓↓
programming-shop.hatenablog.com

Ruby on Rails開発のインターン (Day 36 最終日)

こんにちは、皆さん!

ついにインターン最後の日がやってきた!時間がたつのって本当に早い。インターン初日がまるで昨日のことのように感じられる。振り返ってみると、弁当たくさん作ったな(笑)
まあ、結果的にプログラミングに関して様々な知識を身につけられた気がする。すごくためになるいい経験だった。
最後の日に関してだが、おそらく新しくこれとしたことを始めることはないだろうが、ここまで僕が書いてきたコードの整理などをしてちゃんと他の人に引き継いでもらえるようにすることが主となるかな。最後の日も楽しんでいこう!


  • トピック:
  1. ネステッドルートを使い、Railsにおけるルートを効率よく定義する


  • 疑問:


  • 問題:


  • 学習した内容:
  1. Railsでルートを効率よく定義する方法


  • 今後やってみたいこと:


  • リソース:
  1. Rails のルーティング | Rails ガイド


ネステッドルートを使い、Railsにおけるルートを効率よく定義する

なんとここまで来て、やっと長いURLをネステッドルートで定義した方が効率がよく、コードとしてもきれいに見えることを知った。
今回はRailsガイドでその基礎を学んだ。(Rails のルーティング | Rails ガイド

この機能は難しくないし、僕も結構好き。もう本当にコードがきれいになる。
例えば、ネステッド状態のコントローラー、post/:id/image/:id(簡単に言うと、たくさんの写真を持ったたくさんの投稿を持つウェブサイトであり、このように指定することでその中の一つの投稿の一つの写真を出してくれる)。このURLを書くときにshowアクションのためだけにこう下記のように書きたくなるかもしれない。

get 'post/:id/image/:id', to: 'images#show'

しかし、これをさらにほかのアクションに対してもやらなくていけなく、それはまた大変な量のコードなのであり、間違いも発生しやすい。
だが、下記のようにネステッドの機能を使うことでこれがすごく簡単になるのだ。

resources :posts do
  resources :images
end

これだけで基礎的なRESTfulのアクションすべてを作り出したことになる。

もちろんいくつかのアクションに制限をかけたいときも簡単。例えば、投稿のeditアクションだけをなくしたいのなら

resources :posts, except: [:edit] do
  resources :images
end

ネステッドルートの更にいいところはcollectionフレームが使えることだ。これがあるだけでRESTfulに該当しない基本的でないアクションも簡単に定義することができるのだ。例えば、helloアクションをpost controllerに追加したいとする。そしたら、posts/helloでそのURLを構築したいのなら、普通、下記のようにすればできる。

get 'posts/hello', to: 'posts#hello'

しかし、collectionがあればこのように書き換えられる。

resources :posts do
  collection do
    get 'hello'
  end
end

これはより簡単だし、何より見やすい。あとでここに何か追加したいときはそのままこの枠の中に足すだけで前半部分のposts/をもう入れなくて済む。また、posts/部分が変わる場合も一か所だけ変えればすべてが一緒に変わるという。

まとめ

というわけで、僕の短期インターンに幕を閉じるときがやってきた。僕はとにかくこの自由でフレンドリーな環境が大好きだ。ここでは本当にたくさんのことを学ぶことができた。Railsに限らず、どうやってやることリストを管理し、効率よく仕事を進めていくかなど一般的で共通なスキルも学べた。大人として成長できた印象を受ける。個人的に給料以外はすべて納得だった(笑) まあ、スキルアップして次はもっとたくさん払ってくれるところ探すしかないね(笑)
最後の一日ということで、新しいことを始めることもできなかったが、存在するバグをいくつかすぐに直すことができたのでいいとしよう。最後にこの小さなコミュニティーに貢献できてよかった。
最後にマネージャーと少しこれからの僕のプランについて話し合った。彼は僕が来学期を終えた後、どんなことをするのか結構興味津々であった。今のところ、僕の考えでは、Airbnb, Twitter, Google, Microsoftのような大きなIT会社で働いてみたいなとは思っている(僕なんかを採用してくれるのならの話だが(笑))。明るい自分の将来を願いつつ、2か月間本当にお世話になりました。


ご精読ありがとうございました。では、また次回まで✌





Day 35はこちら↓↓
programming-shop.hatenablog.com