コードチャレンジ」というイベントを開催した。そこで披露された松田さんの模範解答を紹介する。総研スタッフ/宮みゆき)作成日:13.02.01Railsのスキルアップに加え、オープンソースの作法も学べるエンジニアやクリエイターが情報を発信、収集、議論するためのネットワークサイト「Forkwell」とITエンジニア向けの実務スキル評価サービス「CodeIQ」。コードチャレンジ」である。Railsのコミッターである松田明さんを擁するForkwellの開発チームが、実際のForkwellコードを使用したRailsの課題に関する問題を作成。これらの問題をイベントの1週間前からCodeIQで公開し、参加者を募集した。課題問題は3問あり、Railsの基本編から応用編、4.0先取り編で構成されていたため、参加者も初心者からベテランまで、幅広いスキルの人が集まった。当日は参加者が一緒にコーディングした後、コードレビューし合ったり、松田さんからの解答解説やフィードバックが行われた。正解を出した人にはTシャツやパーカーなどのグッズのプレゼントがもらえるなど、楽しみながらスキルアップができ、かつGitHubを使ってパッチを送るなど、オープンソースの作法も学べるとあり、有意義な時間が過ごせたようだ。Forkwellの「読んだ・書いた」の一覧ページを高速化しましょう基本編はRails定番のN+1問題。RailsのActiveRecordは便利だが、非効率なデータベースクエリを発生させることもある。ならないようコーディングするにはどのようにすればいいかを考えるのがこの問題の趣旨。問題は以下のとおりだ。○設問Forkwellの「読んだ・書いた」の一覧ページを高速化しましょう。読んだ・書いたのページで、それぞれの記事の「読んだよ!」の総数や、記事についたコメントの総数も一緒に表示する、という仕様だったとします。https://forkwell.com/publications何も考えずにコードを書いたところ、以下のようになりました。https://github.com/CodeIQ/forkwell/tree/master/question_1しかし、このコードだとレコード数が増えれば増えるほど、SQLの発行数が増える、いわゆる『N+1問題』になってしまいます。Railsが持つ機能を利用してそれを解決することになりました。このコードを、SQLの発行回数ができるだけ少なくなるようにリファクタリングしてください。format-patchで書き出したテキストファイルを解答画面からアップロードしてください。1.8.0.2○解説ポイントは関連名_カウントというinteger型カラムを作ること、デフォルト値を0にする、Publicationの中でちゃんといまのカウントの値を入れておくこと。すればSQLのクエリは1回しか発生しない。この問題は参加者から模範解答が出された。:publication_comments)をincludesし、countメソッドをlengthメソッドに変えるとクエリが減る」という解答もあった。これに対して松田さんは「クエリを減らすという問題からすると正解ともいえるが、それだとconcernsのインスタンス全部とpublication_commentsインスタンスを全部取ってくるので、これが1000件紐づいていると1000個インスタンスが作られてしまい、すごくメモリを使う可能性がある。この方法は実アプリでは使えない可能性がある」と指摘した。Forkwellをレールに乗せましょうForkwellでも実際に発生した、Webアプリケーション開発の現場でありがちな生々しい問題を散りばめた問題。複数のわながあり、それをいかに見つけ、Railsらしいプログラムに仕上げるかが試された。問題は以下のとおりだ。Railsは開発効率がとても良いフレームワークですが、一度そのレールから外れると途端にメンテナンス性の悪いものになってしまいます。Railsが敷いたレールに沿って開発を進めようとします。開発を進めていく上で、どうしてもコードに負債を残していってしまうことはよくあります。今回問題になっているRailsアプリも、コードに大量の負債をかかえてしまいました。Rails「らしい」コードにリファクタリングしましょう。format-patchで書き出したテキストファイルを解答画面からアップロードしてください。"#{@publication.title}の著者にあなたを追加できませんでした。1.8.0.2○解説user.skilltags.include?で重要なのは、バリデーション処理をコントローラーからモデルに移した点である。publications#add_skilltagのRESTfulじゃないメソッドは、skillコントローラーをつくってそこに移動させた。skilltagではないかというと、中間の見えないリソースに対するCRUD操作と解釈したため。UsersControllerのところでfind_by_nameの後に「!」マークをつける、AuthorshipsControllerを作成したなど、変更する箇所はいろいろある。ちなみに、なぜauthorshipsというネーミングにしたか。Hansson氏(DHH)が日本Rubyカンファレンス2006で行った講演を聴いた人ならわかると思うが、同講演でDHHはユーザーとユーザーが紐付く見えない関連を表すコントローラーをfriendshipと名付けていたと思うのだが、それをもじってみた。authorshipsというネーミングにするのが、37signalsが考えるRails的なネーミングというイメージを抱いたから。これが正しいとはいえないが、好ましく思っている。この問題の回答を披露した参加者は3人。その参加者の中には「add_skilltagのコントローラーでの登録処理をまとめ、モデルで実行するようにした」と回答した人も。この「ビジネスロジックをモデルに書く」という発想に、松田さんは「考えたこともなく、目からうろこの思い。ここはビジネスロジックと言うほどでもないので、コントローラーでいいのでは」と解説していた。4に対応させましょう最後は将来、Rails4に移行する際に誰もが陥るであろう、Rails4で一番面倒くさい変更点への対処法を予習するための問題だ。assignment脆弱性への新しい対応策として、strong_parametersが導入されます。以下のリポジトリにあるモデルを、strong_parametersを使って書きなおしてください。format-patchで書き出したテキストファイルを解答画面からアップロードしてください。1.8.0.2○解説4.0ではMassAssignmentSecurityが使えない。その部分を4で新たに採用されたStrongParametersというライブラリを使って、コントローラーに書き換えることになる。GitHub上にあるRailsのドキュメントを見ればわかるが、(person_params)でその下に宣言しているプライベートメソッドを呼び出すのだが、それがあまり洗練されていない。そこで試して欲しいのが、GitHubのasakusarbで公開している「action_args」というプラグイン。模範解答例でもこのプラグインを使用している。実際、Forkwellの開発でも使っており、運用実績もあるので、安心して活用して欲しい。このパラメータを使ったとしてもStrongParametersの対応は非常に大変な作業である。protected_attributesというプラグイン使うという手もあるが、将来的に4への移行を考えている場合は、今後3で開発するアプリについてはStrongParametersを使うことをお勧めする。見える「Forkwell」と「CodeIQ」。両サービスともエンジニアに役立つものを提供したいという思いは同じ。今回のイベントはその第一歩。Forkwellの担当者からも「これからもエンジニアのためになる面白いイベントを共に開催していく話になっています。そのときはみなさん、ぜひ参加してくださいね」と語り、同イベントは盛況のうちに閉幕した。「html5j.org」管理人で、HTML5のエバンジェリストとして知られる白石俊平氏が、また新しい試みを始めた。企業内でGitHubを使うためのサービス「GitHub:Enterprise(GHE)」。企業の第一線で働いているエンジニアに、直接実力を評価してもらい転職する。Tech総研リクルートグループサイトへ。