rails作業日誌
前書き
今日は『Ruby on Rails5 アプリケーションプログラミング』での学習ができなかったので作業日誌です。あと、ここに書いてあることは単なる学習記録なので事実とは関係がない場合があります。ご了承ください。
外部キー制約の追加について
そもそも外部キーとは?
外部キーについては以前も取り上げたが、正確に理解していないようだったので、整理しておく。外部キーは例えばcompaniesテーブルに従属するstaffsテーブルにおける、company_idのことである。ただ、staffsテーブルが単にcompany_idを持っているだけではそれは外部キーではない。それが外部キー制約を持っていて初めて外部キーになる。大事なのは制約の方。
外部キー制約とは?
外部キー制約とは、そのカラムに参照先のテーブルの主キーの値以外を入れてはいけないという制約のこと。その制約のかかっているカラムのことを外部キーと呼ぶ。参照先テーブル_idという名前にすると自動的に外部キーになるわけではない。なので必ずしも参照先テーブル_idという名前でなくても良い。ただ、railsのdefaultではそうなっているのでそうしておいたほうがいい。
外部キーの設定方法
外部キーを設定するのに必要なものは、参照先テーブルの主キーと参照先テーブル_idという名前のカラムと外部キー制約の3つということになる。scaffoldを組む際には
rails generate scaffold staff company:references
のようにするとstaffとcompanyの主従関係が自動的に生成され(companyモデルには別途has_many等の記述が必要)上の3つのうち主たるテーブル以外の2つが勝手に出来上がる。
外部キー制約の追加
既存のテーブルに後から外部キーを設定するには、マイグレーションファイルを作って
class AddCompanyIdToStaffs < ActiveRecord::Migration[5.2] def change add_reference :staffs, :company, foreign_key: true end end
のように定義してマイグレーションする。そうすればcompany_idとその外部キー制約が出来上がる。
add_referenceは
add_reference(テーブル名, リファレンス名 [, オプション])
のように使用する。
その3つのうちの外部キー制約のみ設定したい場合はadd_foreign_keyを使う。同様にマイグレーションファイルを作って、
class AddForeignKeyToStaffs < ActiveRecord::Migration[5.2] def change add_foreign_key :staffs, :companies end end
のようにする。add_foreign_keyは
add_foreign_key :対象のテーブル, :指定先のテーブル
のように使う。これはcompany_idという名前のカラムがあることを前提にしているので、ない場合はエラーになる。
scaffoldでのnewの流れとbcrypt
scaffoldは便利だけど自動でできてしまうだけに流れがよくわからなくなる時があるので整理した(『Ruby on Rails5 アプリケーションプログラミング』第3章の復習)。あとパスワードでbcryptをハッシュ化している。
GET /companies/newでurlを受けると
resources :companies
のルートで内部的に定義されているのでcompaniesコントローラーのnewメソッドが処理される。
def new @company = Company.new end
ここでCompanyモデルが初期化されテンプレート変数@companyに格納される。
次にviews/companies/new.html.erbが表示される。メインテンプレートであるnew.html.erb内に
render 'form', company: @company
の記述があり、部分テンプレートviews/companies/_form.html.erbを呼び出していることがわかる。また、第二引数をcompany: @companyとすることで、部分テンプレートでテンプレート変数@companyをcompanyパラメータとして受け取れるようにしている。
呼び出した_form.html.erbを見てみると
<%= form_with(model: company, local: true) do |form| %>
とある。これで@companyがdbにあるときはコントローラーのupdateにとび、ないときにはcreateにとぶという定義をしている。今回はnewなのでcreateに飛ぶ。createではpostで受け取ったパラメータからprivateメソッドのcompany_paramsを実行する。パスワードをハッシュ化する場合はそこで:password, :password_confirmationを受け取っていて、これらが一致した場合のみモデル内のhas_secure_passwordメソッドを受けることによってハッシュ化されると思われる(モデルにはhas_secure_passwordを記述しておかなければならない)。そしてインスタンス変数@companyに格納されて、password_digestにsaveされる。passwordがハッシュ化されたものがpassword_digestである。パスワードのハッシュ化はbcryptのインストールとdbにpassword_digestカラムがあることが前提となっている。
enumとformについて
モデルにenumを
enum status: { draft:0, published:1, deleted:2 }
のように定義して、form
<div class="field"> <%= form.label :status %> <%= form.number_field :status %> </div>
のようにformを作ると、viewから送信するときに
'1' is not a valid status
のようなエラーが出る(これは1を入力した場合)。エラーメッセージをよくみると1に''がついている。数値で入力しているのに受け取るときになぜか文字列になってしまうらしい。enum以外のinteger型は大丈夫なのになんでだろう?これを回避するためにはformをセレクトボックスかラジオボタンにしてvalueを設定しておけば良いとわかった。
<div class="field"> <%= form.label '下書き' %> <%= form.radio_button :status, :draft %> <%= form.label '公開' %> <%= form.radio_button :status, :published %> </div>
のようにして保存することができました。見てわかるようにform.radio_buttonの第二引数にはenumの数値に対応する値をとります。
今日の感想
わかったつもりでわかってないことがいっぱいある。
作業の計画はなるべく細かく具体的に立てたほうが良い。当たり前なんだけど。徹底していきたい。
『Ruby on Rails5 アプリケーションプログラミング』学習日誌 6
前書き
今日も第5章モデルについて学習していきたいと思います。あと、ここに書いてあることは単なる学習記録なので事実とは関係がない場合があります。ご了承ください。
ページ範囲
p.291-311
学習ポイント
コールバックについて
あるモデル操作に対してそれに付随する処理はコールバックとして定義することで同じようなコードがモデルやコントローラに分散するのを防ぐことができる。
マイグレーションについて
テーブルレイアウトを作成・変更するためにマイグレーションという機能がある。この機能は開発の途中での構成の変化にも対応できる。マイグレーションファイルには必ず頭にタイムスタンプが振られる。rails側ではこの値を元にそれがすでに実行済みかどうかを判断している。railsではこのマイグレーションファイルをタイムスタンプによって一元的に管理しているため、テーブルの状態を特定の時点まで戻したりすることが可能。バージョンの管理ができるためとても便利。
マイグレーションファイルの作成について
ターミナルから下記のようにコマンドすることでマイグレーションファイルを自動的に作成することができる。
rails generate migration ChangePhoneOfStaffs
20180813110400_change_phone_of_staffsのようなマイグレーションファイルができる。20180813110400の部分がタイムスタンプ。ここではinteger型で定義してしまった電話番号フィールドをstring型に変更したいので下記のようにファイルの内容を変更する。
class ChangePhoneOfStaffs < ActiveRecord::Migration[5.2] def change change_column :staffs, :phone, :string end end
そして
rails db:migrate
でマイグレーションを実行すると実際にstaffsテーブルのphoneカラムのデータ型がstringになる。これはdb/schema.rb内の記述が書き換わっていることから確認できる。
また、コマンドで指定するファイル名について若干の命名規則があり、
Add〇〇Toテーブル名 〇〇:データ型
のようにすることで生成されるファイルの内容が下記のようになる。
class Add〇〇ToStaff < ActiveRecord::Migration[5.2] def change add_column :テーブル名, :〇〇, :カラム名 end end
感想
マイグレーションは単にテーブルを簡単に用意するためのものだと思っていたので仕組みを知ることができ良かった。自分で考えるテーブルの設計は基本間違っているのでどんどん便利に使えるようになりたい。
『Ruby on Rails5 アプリケーションプログラミング』学習日誌 5
前書き
今日も第5章モデルについて学習していきたいと思います。 ソースコードにもコメントで気づいたことについて注釈入れてます。あと、ここに書いてあることは単なる学習記録なので事実とは関係がない場合があります。ご了承ください。
ページ範囲
p.268-290
学習ポイント
アソシエーションについて
アソシエーションとはテーブル間のリレーションシップをモデル上の関係として操作できるようにする仕組みのこと。主キーはそのテーブル上の各データに一意についている番号のことで通常id。そして別のテーブルでその各データをそのテーブルのデータに関連づけたい時には外部キーと呼ばれるものを利用する。外部キーはrailsでは「参照先のモデル名(頭は小文字)_id」の形式で命名するという規則がある。外部キーは言ってみれば別のテーブルのデータが入っている変数のようなものだと理解している。アソシエーションを利用することで
@book = Book.find(1) @reviews = @book.reviews
のような書き方で特定のデータに関連する別のテーブルのデータを取得することができる。
これの二行目は
@reviews = Review.where(book_id: @book.id)
に相当する。2番目の方から考える。Reviewモデルから.where メソッド(ActiveRecord::Relationのメソッド?)で第一引数にそのモデルの属性(book_id:)をとり第二引数にインスタンスのid属性を指定している。それらが==になるのを条件に(where)個別のレコードを@reviewsというテンプレート変数に(配列で?)格納している。
対して一個目の書き方では、@bookインスタンスからreviewモデルのメソッドが使えるようになっており、そのインスタンスに従属する値をにアクセスできるようになっている。これも外部キーの命名規則を定めていて、なおかつアソシエーションを定義しているのでこのようなことが可能になる。テーブルのリレーションで重要な中間テーブルの命名は参照先のテーブル名をアルファベット順に_で繋げたものとするという規則がある。
belongs_to アソシエーション
belongs_toメソッドの引数にはモデル名(頭は小文字)を渡す。これが参照先のテーブルを取得するためのアクセサメソッドにもなる。アクセサメソッドとは内部的に持っている値(変数)を外部から取得するためのメソッドのこと。belongs_toメソッドで参照先のモデルを定義することで参照元のモデルから参照先のモデルのメソッドを使うことができるようになる。
has_many アソシエーション
belongs_toメソッドのみでは参照元→参照先という一方通行の関係しか定義できなかったがhas_manyメソッドを使うことで1対多の双方向の関係を定義することができる。has_manyメソッドでは参照先である引数のモデルを複数形で記述する。has_manyを定義したモデルから参照先のモデルをメソッドとして呼び出すときも複数形にする。戻り値も複数あることが前提となるため、配列で返ってくる。
has_one アソシエーション
has_oneメソッドでは1対1の関係を表現できる。主たるモデルにhas_oneを定義し、従たるモデルにbelongs_toを定義する。引数は単数形とする。1対1の関係では主従関係がわかりにくいがどちらかは0or1になる場合があるのでそちらを従にする。
has_and_belongs_to_many アソシエーション
多対多の関係を表現することができる。リレーショナルデータベースでは多対多の関係を表現する方法が無いのでそれぞれのモデル名を複数形で_で繋げた名前の中間テーブルを用意する。中間テーブルにはそれぞれの外部キーだけ用意して置くことで、DB上の全部の関係を1対多までにとどめておくことができる(主キーもなし)。なお、参照元のテーブルには外部キーは必要ない。中間テーブルの名前を参照先のテーブル名を_で繋いだものにすることによってそれらの中間テーブルであることを表現することができるため。また中間テーブルはDBでの表現方法として用意したものに過ぎないので、モデルを作る必要がない。それぞれの元のモデルにおいてはhas_and_belongs_to_manyを定義することで関係を表現する。多対多の関係には主従関係がないので、それぞれのモデルに記述する。引数にとるモデルは複数形になる。これだけでモデル上では多対多の関係を作ることができる。
has_many through アソシエーション
has_and_belongs_to_manyメソッドでは中間テーブル以上の意味をもつ中間テーブルを扱うことができない。(中間テーブルに命名規則が必要になるため。)例えばbooks, users, reviewsのテーブルがあったとして、books↔︎reviewsは1対多、users↔︎reviewsも1対多、books↔︎usersは多対多の関係になる。このような関係に置いてreviewsは自然とbooks↔︎users間の中間テーブルの役割を果たしているがそれ以上にreviewを管理するテーブルとしての意味が強い。reviewsテーブルもモデルとしてアクセスできる必要があるため名前を変えることができない。そうした場合に利用できるのがhas_manyメソッドの第二引数にthroughをとる方法。
class User < ApplicationRecord has_many :reviews has_many :books, throuth: :reviews end
のようにhas_many :reviewsでreviewとの関係を定義した上でhas_many :books, throuth: :reviewsのようにreviewsを中間テーブルに見立てたbooksとの多対多の関係を定義する。このようにすることによってuserモデル↔︎bookモデル間のメソッドの呼び出しを直接行うことができる。
アソシエーションで追加されるメソッドについて
上記のメソッドでアソシエーションということはモデル新しいメソッドを追加することを意味する。例えばbelongs_toで宣言したモデルからアクセサメソッドとして参照元のモデルを呼び出すことができるのもその一つ。他にもempty?やbuildというメソッドもアソシエーションから生まれる。@book.reviews.buildのように使う。このbuildは新しいモデルを生成するメソッドでこの場合は新しいreviewを一つ作ることになる(保存はされない)。@bookに対して、reviewが一つ増えることになるので1対多か多対多の関係を前提としている。どの関係からどんなメソッドが生まれるのかはそれぞれ違う。これらのメソッドは@book.buildのようには使えない(bookモデルが新しく作られたりはしない)。アソシエーションを定義した上で@book.reviewsを前提として初めて使用することができる。たぶん@book.reviewsとすることでreviewモデルのメソッド + buildなどの新しいメソッドを取得する感じになるのだと思う。(ただ、pryでempty?メソッドを探そうとしたけど見つけられなかった。探し方が悪いんだと思うけど。)いずれにせよ、buildやempty?などのメソッドはアソシエーションという関係性のなかで生まれるメソッドということができるようだ。ちょっと注意が必要そう。
ポリモーフィック関連
一つの子モデルが複数の親モデルをもつ関係性のこと。このような場合は子モデルのテーブルに〇〇_typeと〇〇_idという二つのカラムを用意する。これによって親モデルと外部キーを分けて管理することができる。モデル側の定義としては親モデルでasオプション付きのhas_manyメソッドを宣言し、子モデルでpolymorphicオプション付きのbelongs_toメソッドを宣言することでポリモーフィック関連を定義することができる。
アソシエーションで利用できるオプション
上記のポリモーフィック関連以外にもアソシエーションで利用できるオプションはたくさんある。これらをうまく使うことによってモデルによるデータの扱いがすごく簡単になるようだ。本では表でまとめられているので実際の開発で使えそうなのがあったら積極的に使っていきたい。
今日の感想
ついにアソシエーションで追加されるメソッドについて学習することができて嬉しい。前によくわかってないのに使おうとしてハマったことがあったので。モデルの関係性のなかで新しいメソッドが使えるようになるという考え方が面白いと思う。それ以外でもモデルで不思議だったところが前に比べてかなり知ることができて嬉しい一日だった。
『Ruby on Rails5 アプリケーションプログラミング』学習日誌 4
前書き
今日も第5章モデルについて学習していきたいと思います。 ソースコードにもコメントで気づいたことについて注釈入れてます。
ページ範囲
p.229-267
before_action メソッド, only: アクション
コントローラで上記のように書くとアクションに先立ってメソッドを実行するという意味になる。この場合のメソッドをフィルターと呼ぶ。そしてこのメソッドも同じコントローラ内で定義するが、この場合は意図せず呼び出されるのを防ぐためにprivateメソッドにするのが普通である。
ルート定義(基礎編復習)
ルートはurlパターンとhttpメソッドとそれを呼び出すコントローラーのアクションを指定する必要があるが、(アクションメソッドがない場合は直接viewを返す)フィルターの場合はそれの親のメソッドがルートに影響する。
トランザクション処理とは?
いくつかの処理をひとまとめにして処理が全部成功しなかった場合はをロールバックしてはじめの状態に戻し全ての処理をなかったことにするメソッドのこと。transactionメソッド。トランザクションが確定することをcommitと呼ぶ。
例外処理について
raiseによって意図的に例外を発生させることができる。raiseメソッドには引数としてエラーメッセージを渡すことができる。また例外が発生したときはrescueメソッドを用意しておくとrescue節までジャンプし、その時点から処理を続行することができる。rescue => e で変数eに例外自体をオブジェクトとして格納することができる。この場合の => は少し特殊な書き方に見える。rescueのメソッドなのかな?eはインスタンスメソッドとしてmessageやbacktraceなどのメソッドを持っている。この場合のmessageでは対象の例外であるraiseで引数として渡したメッセージが返ってくる。
form_withについて
ここにあるようにform_tagとform_forはrails5.1で非推奨となっているようです。scaffoldで部分テンプレートを(_form.html.erb)生成したときform_withで書かれていて、バージョン5.0.1を前提としている本書のサンプルコードでうまく動かなくて軽くはまりました。ここで ”利用バージョンは本書検証バージョンに揃えることを強くおすすめします。” を無視したことを思い出した。自分が悪いが、form_withは前の二つに比べて賢くて便利そうでよかった。 ** 検証機能
Active Model にはValidation機能がある(ActiveModel::Validations::〇〇Validatorクラス)。モデルクラスに検証のルールを設けて、不正なデータをDBに入る前にはじくことができる。validatesメソッドでデータ型やlength、正規表現などを指定してデータの形を限定することができる。
非DB系のモデル
ActiveModel::Modelモジュールを利用することでDBと関係を持たないモデルを作ることができる。例えばdbに関係ない検証などと関連づけて使用できる。モデルクラスを定義するときはActiveModel::Modelをincludeして必要な項目をアクセサメソッドで定義する必要がある。
『Ruby on Rails5 アプリケーションプログラミング』学習日誌 3
前書き
今日は第5章モデルについて学習していきたいと思います。
ソースコードにもコメントで気づいたことについて注釈入れてます。
ページ範囲
p.200-229
ポイントまとめ
ActiveRecord::Relation
この章について考えるにあたって前提となるActiveRecord::Relation
について知りたい。ActiveRecordはrailsが標準のO/Rマッパー。O/Rマッパーとはobjectとrelational dbの橋渡しをするためのライブラリ。ActiveRecordがリレーショナルモデルであるdbをオブジェクト化してくれることによってそれぞれのレコードをカラム(属性)によるプロパティを持つオブジェクトとして扱うことができる。ActiveRecordがどこから来たのかというとまず、各モデルはApplicationRecordを継承している。そしてこのApplicationRecord
はmodels/application_record.rbで ActiveRecord::Baseを継承している。なので各モデルとそのインスタンスはActiveRecordのメソッドを使うことができる。findメソッドやクエリメソッドなどもActiveRecordのメソッドである。下記のようにクエリメソッドはその場でdbにアクセスせず、ActiveRecord::Relationのオブジェクトを返す。そのオブジェクトにさらにクエリメソッドを実行させて、メソッドチェーンを作ることができる。メソッドチェーンを作った場合、合体した条件式を戻り値として返すが、オブジェクトそれ自体は変化しない。想像だと、それぞれのオブジェクトがクエリを生成するメソッドを内部的に持っている。そしてそのメソッドはデータのもつ属性に依っているのでorメソッドなどでActiveRecord::Relationのオブジェクト同士を結合する際にはモデルによる互換性がないといけない。
データ取得の方法ークエリメソッド
railsにはwhere, selectなどのクエリメソッドと呼ばれるメソッドが用意されている。
これらのfindやfind_by, allなどのメソッドとの違いはそれが読まれた時点でデータベースにアクセスしないという点。クエリメソッドの場合はそれが読まれた時点ではActiveRecord::Relationのオブジェクトが生成されてそれがviewなどで実行される時点で初めてまとめてクエリとなってdbにアクセスするイメージ。このようにコードが読まれる時点(オブジェクト化)とdb接続のタイミングがずれていることを遅延ロードと呼ぶ。これによってクエリメソッドを繋げて、簡単に複雑なクエリを作ることができる。このような記法のことをメソッドチェーンと呼ぶ。
RESTfulインターフェイスとは?
RESTとはhttpメソッドを使ってurlで表現されているリソースを操作する方法のことで、RESTfulインターフェイスとはRESTを前提としたルーティングのことである。railsではこのRESTfulインターフェイスを前提とした機能設計がなされているためこれを活用するのが効率が良いとされる。
httpメソッド
- GET 取得
- POST 作成
- PATCH 更新
- DELETE 削除
RESTfulインターフェイスの定義方法
resourcesメソッドは引数を各リソースとする。リソースとはdbにあるデータなどのことでモデルに対応させて表現する。resources :users など。この一行だけで汎用性の高いルートがたくさん生成される。rails routesコマンドでどんなルートが定義されているのか確認できる。RESTfulインターフェイスを実現するにはルートによってhttpメソッドやurlパターンを定義しなければならない。それがあて初めてルートを通ることができ、ルートの先でparamsメソッドによって値を受け取ることができる。またparamsの引数はリクエスト情報の属性とするが、これはルートで定義するか、もしくはフォームでpostされた際のidかname?どちらかよくわからないけどどっちかを参照してvalueを受け取るようになっている。
感想
特になし
『Ruby on Rails5 アプリケーションプログラミング』学習日誌 2
前書き
「ruby on rails 5 アプリケーションプログラミング」(山田 祥寛 著)で勉強しています。今日は第4章の途中から学習するのでその記録です。ソースコードにもコメントの形で学んだことについて注釈入れてます。
学習の範囲
p.177~198
ポイントまとめ
レイアウトテンプレート
レイアウトテンプレートとはアプリ全体を通して共通のデザインを定義するテンプレートのこと。railsにより/app/views/layouts/application.erbが自動で生成されており、これをカスタマイズすることで自由にデザインを決めることができる。全てのページを同じレイアウトにする必要がない場合はコントローラー単位やアクション単位でのレイアウトの変更も可能。例えばコントローラー単位での設定は/app/views/layouts/以下にコントローラー名.html.erbというファイルを用意する。また、コントローラークラスの中で明示的にlayoutメソッドを利用すれば引数のレイアウトを指定することもできる。さらにはコントローラーのrenderメソッドでアクション単位でのレイアウト呼び出しも可能。レイアウトテンプレートにおいてページごとに要素を変更する場合はテンプレート変数が使える。
<title><%= @title || 'Rails' %></title>
のようになるこれはもしテンプレート変数@titleがnilの場合は'Rails'が入るいうこと。これは真偽値が確定した時点で計算をやめてその時点での値を返すというrubyの性質を利用している。また、application.erbの個別のviewが埋め込まれる部分はyieldが当てられているが、これはviewをブロックに見立てているという意味になるのかな?いずれにしろ、ここで各viewの情報が受け渡されていると理解している。またprovideやcontent_forなどのヘルパーを使うことでyeildに値を持たせることもできる。親レイアウトをメソッド定義のようなものとして、子レイアウトをブロックのように捉えると、yeildの働きがわかるような気がする。親レイアウトのyeildの置かれた場所で子レイアウトが実行される。このような仕組みを利用してレイアウトを入れ子にし使用することができる。また親レイアウトには子レイアウトから継承することを明示的に記述が必要になる(条件分岐も必要)。これが無いと子レイアウトがそれを通過してきているのに、無視される。部分テンプレートはある意味レイアウトテンプレートの逆で、そのままだけど、パーツをテンプレート化するもの。ファイル名の頭に_をつけるという命名規則があり、これが無いとrailsが部分テンプレートとして認めない。
『Ruby on Rails5 アプリケーションプログラミング』学習日誌 1
前書き
railsを体系的に理解したくて、「ruby on rails 5 アプリケーションプログラミング」(山田 祥寛 著)を買いました。初心者です。とりあえずは第6章までの基本編の理解を目指して頑張ります。あとブログを書くのも初めてです。
学習の進め方について
すでに三章までは学習済みです。折に触れて復習していきたいと思います。
また、この本ではrailsの様々な機能について詳細に説明されていますが、とりあえずの目標はrailsの特徴や規約をなんとなく理解することにあるので、それぞれの機能の考え方をつかむことに焦点を当てていきたいと思います。
github
学習した範囲
p.104~p.177
ポイントまとめ
テンプレートファイルの生成
$ rails generate controller view keyword
でコントローラークラスと同時にテンプレートファイルを自動生成することができる。
この場合はviewコントローラーのkeywordアクションとview/keyword.html.erbを生成している。なおテンプレートファイルを単独で生成するコマンドはない。
ビューヘルパーとは?
ヘルパーメソッドとはよく行われる処理をrailsがあらかじめメソッド化してあるもののこと。基本的にviewに使われる。ここではform生成での実用例が挙げられている。form_tagは前提とするモデルの存在しないフォームの生成に役に立つ(検索フォームなど)。一方でform_forは特定のモデルに対する編集フォームなどを簡単に生成できる。いずれもviewのerbにメソッドとして埋め込む形で使用する。フォームを一から作る必要がなく、rubyの文法で動的にフォームを作成することができる。またcollection_selectメソッドを使えばセレクトボックスのオプションを引数のオブジェクトの持っている属性によって動的に生成することができる。
加工系ヘルパー
railsは各種データを加工してブラウザに渡すためのヘルパーメソッドを持っている。これにより、データ自体を動的に整形することができ、見やすく統一感のあるviewに貢献する。
ここまでの感想
基本編に入った段階でかなり詳細な内容になり、理解していくのが大変だったが、その分railsの具体的な考え方に触れることができたようなできなかったような気がした。最初は全く理解できなくて困ったけどだんだんすごいところも見えてきたような気がする。