googletag.defineSlot('/21812778492/blog_728x90_common_eyecatch01_adsence', [728, 90], 'div-gpt-ad-1566564252373-0').addService(googletag.pubads()); googletag.defineSlot('/21812778492/blog_300x250_common_fixed02_adsense', [[300, 250], [336, 280]], 'div-gpt-ad-1565198391774-0').addService(googletag.pubads()); HTTPメソッドがGET/POST/PATCH/PUT/DELETE/HEADのいずれかの場合にtrueを返す, レスポンスのステータスコード (200 OK、404 file not foundなど), レスポンスストリームが1つ作成されるたびに新しいスレッドが作成され、元のスレッドからスレッドローカルな変数がコピーされます。スレッドローカルな変数が増えすぎるとパフォーマンスに悪影響が生じます。また、スレッド数が多すぎても同様にパフォーマンスが低下します。, レスポンスストリームを閉じることに失敗すると、対応するソケットが永久に開いたままになってしまいます。レスポンスストリームを使う場合は、. create test/system/articles_test.rb, exists test/integration/ index / show / new / create / edit / update / destroy がそれぞれ何をす … Railsでは、テストデータの定義とカスタマイズはフィクスチャで行うことができます。 }); この記事では、Controllerの基本的な使いかたとして、以下のような内容を説明します。, Controllerには、ViewやModelを統括するというもっとも重要な役割があります。, もっとも重要な役割を粛々と行うためにも、Controllerの基礎をしっかりと学び、ViewやModelとの連携をスムーズにできるようにしておきましょう。, MVCは、以下の3つのコンポーネント(構成要素)から構成されるデザインパターンです。, Controllerはユーザーの意思を反映したHTTPリクエストを受け取り、ModelやViewと連携しながら、ユーザーに返すデータを決定する処理を担当します。, Controllerの使いかたを理解するために、Ruby on Railsをインストールしておきましょう。, 私は、以下の記事を参考に、VirtualBoxで作成した仮想パソコンにインストールしたLinux Mintに、Ruby on Railsの開発環境を作成しました。, 基本的には記事の手順に従って操作しますが、app/samurai/sample1ディレクトリを作成する代わりに、app/samurai/controller-demoディレクトリを作成しました。, また、Ruby on Railsを起動して、ブラウザで画面が表示されることを確認したら、いったんRuby on Railsを終了してから次に進みます。, Controller(+基本的なViewやルーティング)を作成するには、以下のコマンドを使用します。, Modelと結びつきがある場合は、Controller名をGrapesのように複数形にします。, Railsでは、使用するファイルなどを名前によって自動的に推測するため、命名規則に従っていないと予期しないエラーが発生してしまいます。, 名前を正しく決める必要があり、それだけなら欠点のように思えますが、その代わりに冗長なコードが減るという利点があります。, Controller(+基本的なViewやルーティング)を削除するには、以下のコマンドを使用します。, rails generate controllerコマンドで作成されたファイルが削除されます。, ここで、config/routes.rbに設定されたルーティングの設定は残っていることに注意してください。, config/routes.rbには、他のControllerのアクションに関するルーティングも記述されているため、ファイルを削除すると問題になるためです。, そこで、config/routes.rbを編集して、Grapesに関するルーティングを削除しましょう, params[:id]のように書くと、Railsで送られてきた値(パラメータ)を受け取れます。, redirect_to action: :example1のように書くと、自動的なページの切り替え(次のアクションの呼び出し)を簡単に実装できます。, flash[:notice] = “任意のメッセージ”のように書くことで、任意のメッセージをViewに表示できます。, render "help"と書くことで、help(app/views/pages/help.html.erb)テンプレートを表示できます。, 一つのControllerにたくさんのアクションを記述しすぎると、コードが管理しにくくなったり、テストに時間がかかりすぎたりする問題が起きます。, そんなときは、ActiveSupport::Concernを使うことで、アクションをモジュール化できます。, Viewの場合は部分テンプレート(partial)を使って小分けにしますが、Controllerではモジュール化して小分けにします。, ここからは、実際にActiveSupport::Concernを使ってみましょう。, scaffoldを使ってWebアプリを作成すると、ルート構成がRESTfulの考え方に従って作成されます。, 今回はActiveSupport::Concernを使って、これらのアクションの一部を別のファイルに切り出してみましょう。, 具体的には、app/controllers/concernsディレクトリにファイルを作成します。, (1)app/controllers/concerns/banana_one.rbを以下の内容で作成します。, Railsらしく、module名は、頭文字大文字、単語の境界に「_」無しで、ファイル名は、頭文字小文字、単語の境界に「_」有りという命名規則があります。, 上の例のように、module名をBananaOneにした場合は、ファイル名はbanana_one.rbにします。, この命名規則に従っていないと、ActiveSupport::Concernが適切に読み込めません。, (2)app/controllers/bananas_controller.rbを以下のように修正します。, (3)ブラウザで「http://localhost:3000/bananas」にアクセスします。, ActiveSupport::Concernでモジュール化したindexアクションもしっかり呼び出されていますね。, 同様に、以下のURLにアクセスして、各アクションが呼び出せることを確認してみてください。, このように、include BananaOneで、app/controllers/concerns/banana_one.rbの内容を読み込み、モジュール化する前と同様に呼び出せるのです。, なお、モジュール化したBananaOneは、別のControllerからも呼び出せるため、共通のアクションが複数のControllerに存在する場合にも活用できます。, respond_toを使うと、URLにあわせて表示するフォーマットを切り替えられます。, 具体的には、以下のようなコードで、htmlとJSONとXMLを切り替えられるようになります。, respond_toの使いかたは、以下の記事で詳しく説明していますので、ぜひご覧ください。, 作成方法と命名規則さえわかっていればControllerを作成できますが、このページで紹介したような機能をしっかりマスターしておけば、Webアプリを開発するときに必要な基本的な機能はカバーできるでしょう。, また、実装していく段階で、ファイルが大きくなりすぎたと思ったらActiveSupport::Concernを活用したモジュール化を検討してはいかがでしょうか。, 当プログラミングスクール「侍エンジニア塾」では、これまで6000人以上のエンジニアを輩出してきました。 Testing Rails ApplicationsThis guide covers built-in mechanisms in Rails for testing your application.After reading this guide, you will know: Rails testing terminology. googletag.pubads().enableSingleRequest(); 過去に閲覧した記事の履歴をリスト化し、最後に閲覧した記事から数えて10件を表示する。, 上の文言だけだとやや抽象的なので、もう少し設計に落とし込んだ上で create app/assets/stylesheets/welcome.scss, # routes.rbで利用できるDSLについて詳しくはhttp://guides.rubyonrails.org/routing.htmlを参照, Prefix Verb URI Pattern Controller#, welcome_index GET /welcome/index(. メシ屋リサーチと温泉が趣味。. (ルーティングの設定は省略しますが、下記のアクションそれぞれに対してルーティングが必要です。念の為。), UserとArticleの中間テーブルとして、BrowsingHistoryが存在している形です。 +++ actual 2 runs, 1 assertions, 0 failures, 1 errors, 0 skips, Finished in 0.027034s, 73.9810 runs/s, 110.9715 assertions/s. # "chapters_attributes" => { "1" => {"title" => "First Chapter"}, # "2" => {"title" => "Second Chapter"}}}}, # Cookie ベースのデフォルトは特に機密性の高い情報を保存する目的で使うべきではありません。, # (セッションテーブルの作成は"rails g active_record:session_migration"で行なう), # Rails.application.config.session_store :active_record_store. 本記事では…, controllerの作成方法・controllerの命名規約・controllerの削除方法, Rails controllerはブラウザ・model・viewとの仲介役で、「なんでも屋」, Rails controllerはmodelとviewの仲介役のようなもので、非常に重要な役割を担っている, Rails check_box_tagでcheckboxを生成!初心者でもわかる!. You can run multiple files and directories at the same time: --no-plugins Bypass minitest plugin auto-loading (or set $. new_history = @article.browsing_histories.new create test/fixtures/articles.yml, invoke test_unit Show progress processing files. (article_id: "#{params[:id]}")で, 結果的に、ユーザーIDも記事IDも同じになっている閲覧履歴は存在しているか?ということを調べています。 Finished in 0.023918s, 41.8090 runs/s, 41.8090 assertions/s. :format) articles#, root GET / welcome#, == CreateArticles: migrating ================================================== var googletag = googletag || {}; "の後に置かれます。2番目のパラメータは、「POSTデータ」と呼ばれるものです。POSTデータは通常、ユーザーが記入したHTMLフォームから受け取ります。これがPOSTデータと呼ばれているのは、HTTP POSTリクエストの一部として送信されるからです。Railsでは、クエリ文字列パラメータの受け取り方とPOSTデータの受け取り方に違いはありません。どちらもコントローラ内ではparamsという名前のハッシュでアクセスできます。, paramsハッシュは、一次元のキー・値ペアしか格納できないということはありません。配列や、ネストしたハッシュを格納することもできます。値の配列をフォームから送信したい場合は、以下のように空の角かっこ[]をキー名に追加してください。, [や]はURLで使えない文字なので、この例の実際のURLは/clients?ids%5b%5d=1&ids%5b%5d=2&ids%5b%5d=3のようになります。これについては、ブラウザで自動的にエンコードされ、Railsがパラメータ受け取り時に自動的に復元するので、通常は気にする必要はありません。ただし、何らかの理由でサーバーにリクエストを手動送信しなければならない場合には、この点を忘れないようにする必要があります。, これで、受け取ったparams[:ids]の値は["1", "2", "3"]になりました。もうひとつ注意すべきは、パラメータの値はすべて「文字列」であることです。Railsはパラメータの型推測や型変換を行いません。, paramsの中に[nil]や[nil, nil, ...]などの値があると、すべて自動的に[]に置き換えられます。この動作は、デフォルトのセキュリティ上の理由にもとづいています。詳しくは セキュリティガイド を参照してください。, フォームから、中かっこ`[]の中にキー名を含めたハッシュを送信するには以下のようにします。, このフォームを送信すると、params[:client]の値は{ "name" => "Acme", "phone" => "12345", "address" => { "postcode" => "12345", "city" => "Carrot City" } }になります。params[:client][:address]のハッシュがネストしていることにご注目ください。, このparamsハッシュは一見ハッシュのように振る舞いますが、キーとしてシンボルと文字列のどちらでも指定できる点がハッシュと異なります。, Webサービスを開発していると、パラメータをJSONフォーマットで受け取れたら便利なのにと思うことがあります。Railsでは、リクエストの「Content-Type」に「application/json」が指定されていれば、パラメータが自動的にparamsハッシュに読み込まれ、以後は通常のparamsハッシュと同様に操作できます。, params[:company]では{ "name" => "acme", "address" => "123 Carrot Street" }という値を受け取ります。, 同様に、初期化設定でconfig.wrap_parametersをオンにした場合や、コントローラでwrap_parametersが呼び出された場合、JSONパラメータのルート要素を安全に取り除くことができます。このときデフォルトでは、このパラメータが複製されてコントローラ名に応じたキー名でラップされます。従って、上のJSONリクエストは以下のように書けます。, データの送信先がCompaniesControllerであれば、以下のように:companyというキーでラップされます。, キー名のカスタマイズや、ラップしたい特定のパラメータについてはAPIドキュメントを参照してください。, 従来のXMLパラメータ解析のサポートは、actionpack-xml_parserという別のgemに切り出されました。, paramsハッシュに必ず含まれるキーは:controllerキーと:actionキーです。ただしこれらの値には直接アクセスせず、controller_nameとaction_nameという専用のメソッドを使ってください。ルーティングで定義されるその他の値パラメータ (idなど) にもアクセスできます。例として、「有効」と「無効」のいずれかで表される顧客のリストについて考えてみましょう。「プリティな」URLに含まれる:statusパラメータを捉えるためのルートを1つ追加してみましょう。, この場合、ブラウザで/clients/activeというURLを開くと、params[:status]が「active」(有効) に設定されます。このルーティングを使うと、あたかもクエリ文字列で渡したかのようにparams[:foo]にも"bar"が設定されます。コントローラでもparams[:action]をindexとして、params[:controller]をclientsとして受け取ります。, コントローラでdefault_url_optionsという名前のメソッドを定義すると、URL生成用のグローバルなデフォルトパラメータを設定できます。このようなメソッドは、必要なデフォルト値を持つハッシュを必ず1つ返さねばならず、そのハッシュのキーはシンボルでなければなりません。, これらのオプションはURL生成の開始点として使われるので、url_for呼び出しに渡されるオプションで上書きできます。, ApplicationControllerでdefault_url_optionsを定義すると、上の例で示したように、すべてのURL生成で使われるようになります。このメソッドを特定のコントローラで定義すれば、そのコントローラで生成されるURLにだけ影響します。, 指定されたリクエストでは、生成された単一のURLごとにこのメソッドが実際に呼ばれるわけではありません。パフォーマンス上の理由により戻り値であるハッシュがキャッシュされるので、呼び出しは最大でもリクエストごとに1回までとなります。, strong parametersを用いることで、Action Controllerのパラメータが許可されるまでActive Modelの「マスアサインメント」に利用されることを禁止できます。つまり、多くの属性を一度に更新したい場合は、どの属性のマスアップデートを許可するかを開発者が明示的に指定しなければなりません。大雑把にすべての属性の更新を一括で許可してしまうと、外部に公開する必要のない属性まで誤って公開してしまう可能性が生じるため、そのような事態を防ぐための機能です。, さらに、パラメータの属性に「必須 (required)」を指定することで、事前に定義したraise/rescueフローによって、渡された必須パラメータが不足している場合に「400 Bad Request」で終了させることもできます。, :idキーがparamsにあり、それに対応する許可済みスカラー値に:idキーがあれば、ホワイトリストチェックをパスします。この条件を満たさない場合は、:idキーはフィルタで除外されます。これにより、外部からハッシュなどのオブジェクトを不正に注入できなくなります。, スカラーで許可される型は、String、Symbol、NilClass、Numeric、TrueClass、FalseClass、Date、Time、DateTime、StringIO、IO、ActionDispatch::Http::UploadedFile、Rack::Test::UploadedFileです。, 「paramsの値には許可されたスカラー値の配列を使わなければならない」ことを宣言するには、以下のようにキーに空の配列を対応付けます。, ハッシュパラメータやその内部構造の正しいキーをすべて明示的に宣言できない場合や、すべて宣言するのが面倒な場合があります。次のように空のハッシュを割り当てることは一応可能です。, ただしこのように指定してしまうと任意の入力を受け付けてしまうため、利用には十分ご注意ください。この場合permitによって、受け取った構造内の値が許可済みのスカラーとして扱われ、それ以外の値がフィルタで除外されます。, こうすることで、:log_entryパラメータハッシュとすべてのサブハッシュが「許可済み(permitted)」としてマーキングされ、許可済みスカラーであるかどうかがチェックされなくなってあらゆる値を受け付けるようになります。ただし、permit!はくれぐれも慎重にお使いください。現在のモデルの属性はもちろん、将来モデルに追加される属性も一括で許可してしまうためです。, この宣言では、name、emails、friends属性が許可されます。ここでは、emailsは許可を受けたスカラー値の配列であることが期待され、friendsは特定の属性を持つリソースの配列であることが期待され、どちらもname属性(許可を受けたあらゆるスカラー値を受け付ける)を持ちます。また、hobbies属性(許可を受けたスカラー値の配列)や、family属性(同じく、許可を受けたあらゆるスカラー値を受け付ける)を持つことも期待されます。, 今度はnewアクションでも許可済み属性を使いたいところです。しかし今度はnewを呼び出す時点ではルートキーがないので、ルートキーに対してrequireを指定することができないという問題があります。, このモデルのaccepts_nested_attributes_forクラスメソッドを使えば、関連付けられたレコードを更新または削除できます。このメソッドは、idと_destroyパラメータに基づいて動作します。, キーが整数のハッシュは異なる方法で処理されます。これらは、あたかも直接の子オブジェクトであるかのように属性を宣言できます。has_many関連付けとともにaccepts_nested_attributes_forメソッドを使うと、このようなパラメータを取得できます。, 次のような状況を想像してみましょう。製品名と、その製品名に関連する任意のデータを表すパラメータがあるとします。そして、この製品名もデータハッシュ全体もまとめて許可したいとします。, strong parameter APIは、最も一般的な使用状況を念頭に置いて設計されています。つまり、あらゆるパラメータのフィルタ問題を扱える「銀の弾丸」ではありません。しかし、このAPIを自分のコードに混在させてアプリの実情に対応しやすくなります。, Railsアプリケーションにはユーザーごとにセッションが設定されます。前のリクエストの情報を次のリクエストでも利用するためにセッションに少量のデータが保存されます。セッションはコントローラとビューでのみ利用できます。また、以下のようにさまざまなストレージを選べます。, あらゆるセッションは、セッション固有のIDをcookieに保存します (注意: RailsでセッションIDをURLで渡すことはセキュリティ上の危険があるため許可されません。セッションIDは必ずcookieで渡さなくてはなりません)。, 多くのセッションストアでは、このIDは単にサーバー上のセッションデータ (データベーステーブルなど) を検索するために使われています。ただしCookieStoreは例外的にcookie自身にすべてのセッションデータを保存します(必要であればセッションIDも利用できます)。そしてRailsではCookieStoreがデフォルトで使われ、かつRailsでの推奨セッションストアでもあります。CookieStoreの利点は、非常に軽量であることと、新規Webアプリケーションでセッションを利用するための準備がまったく不要である点です。cookieデータは改竄防止のために暗号署名が与えられています。さらにcookie自身も暗号化されているので、内容を他人に読まれないようになっています。(改ざんされたcookieはRailsが拒否します), CookieStoreには約4KBのデータを保存できます。他のセッションストアに比べて少量ですが、通常はこれで十分です。利用するセッションストアの種類にかかわらず、セッションに大量のデータを保存することはお勧めできません。特に、セッションに複雑なオブジェクト (モデルインスタンスなどの基本的なRubyオブジェクトでないもの) を保存することはお勧めできません。このようなことをすると、サーバーがリクエスト間でセッションを再編成できずにエラーになることがあります。, ユーザーセッションに重要なデータが含まれていない場合、またはユーザーセッションを長期間保存する必要がない場合 (flashメッセージで使いたいだけの場合など) は、ActionDispatch::Session::CacheStoreを検討してください。この方式では、Webアプリケーションに設定されているキャッシュ実装を利用してセッションを保存します。この方法のよい点は、既存のキャッシュインフラをそのまま利用してセッションを保存できることと、管理用の設定を追加する必要がないことです。この方法の欠点はセッションが短命になり、セッションがいつでも消える可能性がある点です。, 別のセッションメカニズムが必要な場合は、イニシャライザを変更することで切り替えられます。, Railsは、セッションデータに署名するときにセッションキー(=cookieの名前)を設定します。この動作もイニシャライザで変更できます。, :domainキーを渡して、cookieで使うドメイン名を指定することもできます。, Railsは、config/credentials.yml.encのセッションデータの署名に用いる秘密鍵を (CookieStore用に) 設定します。この秘密鍵はrails credentials:editで変更できます。, CookieStoreを使用中にsecret_key_baseを変更すると、既存のセッションがすべて無効になります。, コントローラ内では、sessionインスタンスメソッドを使ってセッションにアクセスできます。, セッションは遅延読み込みされます(lazy loaded)。アクションのコードでセッションにアクセスしなかった場合、セッションは読み込まれません。つまり、セッションにアクセスしていなければセッションを無効にする必要はまったくありません。アクセスしないようにすればセッションは無効になります。, flashはセッションの中の特殊な部分であり、リクエストごとにクリアされます。つまりflashは「直後のリクエスト」でのみ参照可能になるという特徴を持ち、エラーメッセージをビューに渡したりするのに便利です。, flashのアクセス方法はセッションとほとんど同じで、ハッシュとしてアクセスします (これをFlashHash インスタンスと呼びます)。, 例として、ログアウトする動作を扱ってみましょう。コントローラでflashを使うことで、次のリクエストで表示するメッセージを送信できます。, flashメッセージはリダイレクトの一部として割り当てることもできることにご注目ください。オプションとして:notice、:alertの他に、一般的な:flashも使えます。, このdestroyアクションでは、アプリケーションのroot_urlにリダイレクトし、そこでメッセージを表示します。flashメッセージは、直前のアクションでflashメッセージにどのようなメッセージを設定していたかにかかわらず、次に行われるアクションだけですべて決まりますのでご注意ください。Railsアプリケーションのレイアウトでは、警告や通知をflashで表示するのが通例です。, このように、アクションで通知(notice)や警告(alert)メッセージを設置すると、レイアウト側で自動的にそのメッセージが表示されます。, flashには、通知や警告に限らず、セッションに保存可能なものであれば何でも保存できます。, flashの値を別のリクエストにも引き継ぎたい場合は、keepメソッドを使います。, デフォルトでは、flashに値を追加すると直後のリクエストでその値を利用できますが、次のリクエストを待たずに同じリクエスト内でこれらのflash値にアクセスしたい場合があります。たとえば、createアクションに失敗してリソースが保存されなかった場合に、newテンプレートを直接描画するとします。このとき新しいリクエストは行われませんが、この状態でもflashを使ってメッセージを表示したいこともあります。このような場合、flash.nowを使えば通常のflashと同じ要領でメッセージを表示できます。, Webアプリケーションでは、cookieと呼ばれる少量のデータをクライアントのブラウザに保存できます。HTTPは「ステートレス」なプロトコルなので、基本的にリクエストとリクエストの間には何の関連もありませんが、cookieを使うとリクエスト同士の間で (あるいはセッション同士の間であっても) このデータが保持されるようになります。Railsではcookiesメソッドを使ってcookieに簡単にアクセスできます。アクセス方法はセッションの場合とよく似ていて、ハッシュのように動作します。, セッションを削除する場合はキーにnilを指定することで削除しましたが、cookieを削除する場合はこの方法ではなく、cookies.delete(:key)を使ってください。, Railsでは、機密データ保存のために署名済みcookie jarと暗号化cookie jarを利用することもできます。署名済みcookie jarでは、暗号化した署名をcookie値に追加することで、cookieの改竄を防ぎます。暗号化cookie jarでは、署名の追加と共に、値自体を暗号化してエンドユーザーに読まれることのないようにします。