Rails チュートリアル on Cloud9 の学習録(第10章)
決して高いスキルを持っているわけでもないのに、単身、現場に投入させられることが多いので、自社と自身の提供する価値について考えさせられる機会が多い。
サルヴァトーレ・フェラガモは、自身の仕事についてこんな言葉を残している。
足にぴったり合う靴を作るのが靴屋の仕事であって、それができないのならその理由を見つけ出すのが、自分の技術や客に対する靴屋の責任なのだ
この言葉には、技術屋としてとても感銘を受けた。「できないことがある」という、自身のそして技術の限界を理解したうえでなお、職責を果たそうとする姿は素晴らしいと思う。
フェラガモは、履き心地の良い靴を追及するために解剖学も学んだというが、自分は自分の職責を果たすために、何を反省し、何を改善しようと試みてきたのか。自分という価値をどうやって提供すべきなのか考えさせられる一語であった。
それでは、今日はRails チュートリアルの第10章。チュートリアルもあと2章。
10.1 Micropostモデル
もうすっかり忘れてた。テーブルを作る手順は以下の通り。
$ rails generate model Micropost content:string user_id:integer
$ rake db:migrate
$ rake test:prepare
で、必須項目である事定義する為に、Modelのpresenceをtrueにする。
10.1.3 User/Micropostの関連付け
やっとJOIN。1:多の'1'の方はモデルにhas_many <モデル名(複数形)>を、'多'の方にはbelong_to <モデル名> を書く。これで終わり。キーをしていないが、これでいいのだろうか?
10.1.4 マイクロポストを改良する
取り出す順番を指定するには、スコープを使って以下のように取り出す。
default_scope -> { order('created_at DESC') }
findとwhereの使い分けについては、重要そうなので引用しておく。
Micropost.findではなくMicropost.whereを使用しています。whereメソッドは、レコードがない場合に空のオブジェクトを返すので多少テストが書きやすくなるためです (findはレコードがない場合に例外を発生します)。
10.2.1 ユーザー表示ページの拡張
何の気なしに、view/users/_micropost.html.erbとパーシャルを作ってお叱りを受けた。"render @micropost" を使う時は、viewの下に"microposts"を作成して、その下にパーシャルをおく必要がある。
10.3マイクロポストを操作する
やたらテストに失敗したが、その原因は、複数形のつけ間違いが多かった。コントローラーファイルは、"microposts". destory actionで遷移させるページは"micropost"。
10.3.2 マイクロポストを作成する
Static_pages/homeにレンダーを追加する。そして、static_pages/_user_info.html.erb のように、static_pagesの下にパーシャルを作成したが、チュートリアルを確認したら、Sharedの下にパーシャルを作成していたので、移動させた。
エラーメッセージのパーシャルを変更したので、各種レンダーを修正しなければならないのは、わかるが、チュートリアルで指摘している、view/users/new.html.erb にはエラーメッセージのレンダーを配置していない…ので、_field.html.erbを以下のように修正したら、テストをパスした。
<%= render 'shared/error_messages', object: f.object %>
10.3.3 フィードの原型
ここの言っている意味がよく分からん。"Micropost.where(id)"だけでもいいけど、SQLインジェクション対策に"user_id = ?"を入れてるってこと?
Micropost.where("user_id = ?", id)
上の疑問符があることで、SQLクエリにインクルードされる前にidが適切にエスケープされることを保証してくれるため、SQLインジェクションと呼ばれる深刻なセキュリティホールを避けることができます。この場合のid属性は単なる整数であるため危険はありませんが、SQL文にインクルードされる変数を常にエスケープする習慣はぜひ身につけてください。
と、書いてから読み進めたら、以下の内容と同じだと書いてあった。
def feed
microposts
end
10.3.4 マイクロポストを削除する
コードを書いていて、なんか同じようなページを作っていると思ってモヤモヤしていたけど、やっぱり同じコードを書いていた。_micropost.html.erbと_feed_item.html.erbはほとんど同じ内容だ。
で、view/_micropost.html.erb → microposts_controller.erb は理解できる。view/shared/_feed_item.html.erb → _feed.html.erb → model/user.rbのdef feedからマイクロポストの情報を取っているらしい…
たぶんmicropostのビューは純粋に自分の投稿だけを表示させて、feedのビューは11章でフォローしたマイクロポストをhas_manyで表示させるようにするのだろう。
10.5 演習
1.マイクロポストカウントのテスト。なんか冗長な書き方してる気がするけど、テストを通ったからいいか。
describe "正常系:" do
before { fill_in 'micropost_content', with: "Lorem ipsum" }
it "マイクロポストが作成される" do
expect { click_button "Post" }.to change(Micropost, :count).by(1)
end
describe "1件のマイクロポスト" do
before { click_button "Post" }
it { should have_content('1 micropost') }
end
describe "2件のマイクロポスト" do
before { click_button "Post" }
before { fill_in 'micropost_content', with: "2件目ですぞ" }
before { click_button "Post" }
it { should have_content('2 microposts') }
end
end
2. user_pages_specのページネーションのソースコードを丸パクリ。
describe "マイクロポストのページネーション" do
before { 50.times { FactoryGirl.create(:micropost, user: user) } }
before { visit root_path }
after { Micropost.delete_all }
it { should have_selector('div.pagination') }
it "リスト表示する" do
Micropost.paginate(page: 1).each do |micropost|
expect(page).to have_selector('li', text: micropost.content)
end
end
end