Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Merge branch 'master' of github.com:defaude/asciicasts.com-translations

  • Loading branch information...
commit 8a7d548073dc89eeade1f7eac2b0c17736d9220c 2 parents e44b34b + 2c9a92e
@eifion authored
View
191 episodes/316 - Private Pub/ja.html
@@ -0,0 +1,191 @@
+<p><a href="http://railscasts.com/episodes/260-messaging-with-faye">エピソード260</a>では<a href="http://faye.jcoglan.com/">Faye</a>を使ってユーザのブラウザをリアルタイムに更新する方法を紹介しました。Fayeは優れているものの、動作させるまでに少し手間がかかります。完全にセキュアな状態にしたい場合は特にそうです。これを解決するためにRyan Batesが作成したのが、Fayeの上で動作する<a href="https://github.com/ryanb/private_pub">Private Pub</a>というgemです。彼が目指したのは、Railsアプリケーションでリアルタイムイベントをさらに簡単に配信/購読できるようにすることです。</p>
+
+<p>今回扱うアプリケーションはシンプルなチャット用アプリケーションです。ページの下の方にあるテキストフィールドにメッセージを入力して「Send」をクリックすると、ブラウザはメッセージを保存するためにAJAXリクエストを送信し、ブラウザを更新してメインのチャットウィンドウにメッセージを追加します。</p>
+
+<div class="imageWrapper">
+ <img src="http://asciicasts.com/system/photos/943/original/E316I01.png" width="800" height="399" alt="チャットアプリケーション"/>
+</div>
+
+<p>しかしこのアプリケーションには問題があります。複数のチャットクライアントが開いている場合、メッセージが送信されたときにすべてがリアルタイムには更新されません。メッセージを送信したクライアントだけに新しいメッセージが表示されます。他のすべてのクライアントは、メッセージを表示するためにページをリロードする必要があります。この問題を解決する方法はいくつかあります。一つは各クライアントが数秒ごとに新規メッセージを確認するためにポーリングをおこなう方法ですが、ベストなアイデアとはありません。もう一つの方法は、各クライアントでサーバへのソケットコネクションを開いたままにして、新規メッセージが来たらサーバがそれをプッシュして、クライアントにリアルタイムに表示されるようにします。この方法の問題は、Railsのアーキテクチャが長いリクエストを扱うように設定されていないという点です。</p>
+
+<p>FayeとPrivate Pubがこの問題を解決してくれます。その詳細を見る前に、我々のチャットアプリケーションが動作する様子を見てみましょう。まずチャットページのビューテンプレートから始めます。</p>
+
+``` /app/views/messages/index.html.erb
+<h1>Chat</h1>
+
+<ul id="chat">
+ <%= render @messages %>
+</ul>
+
+<%= form_for Message.new, remote: true do |f| %>
+ <%= f.text_field :content %>
+ <%= f.submit "Send" %>
+<% end %>
+```
+
+<p>このテンプレートは<code>messages</code>と呼ばれる部分テンプレート(partial)をrenderしてメッセージのリストを表示し、新規メッセージを作成するためのフォームが含まれています。フォームは<code>remote: true</code>オプションを使用してAJAXリクエストを介して送信されます。フォームが送信されると<code>MessagesController</code>の<code>create</code>アクションに送られます。次にそれを見てみましょう。</p>
+
+``` /app/controllers/messages_controller.rb
+class MessagesController < ApplicationController
+ def index
+ @messages = Message.all
+ end
+
+ def create
+ @message = Message.create!(params[:message])
+ end
+end
+```
+
+<p><code>create</code>アクションはとてもシンプルです。新規の<code>Message</code>レコードを作成しますが、このアクションがAJAXを介して呼び出されてJavaScriptテンプレートを表示するときに、何もレスポンスがないことに注意してください。そのJavaScriptテンプレートは以下のとおりです。</p>
+
+``` /app/views/messages/create.js.erb
+$("#chat").append("<%= j render(@message) %>");
+$("#new_message")[0].reset();
+```
+
+<p>このJavaScriptは、新規に作成されたメッセージをチャットリストの末尾に追加し、新規メッセージを入力するテキストフィールドの中身をクリアします。やりたいことは、このメッセージをすべてのチャットクライアントにbroadcastして、送信したクライアントでだけでなく、すべてで新規メッセージが表示されるようにすることです。Private Pubを利用すれば、これを実現することができます。</p>
+
+<h3>Private Pubのインストール</h3>
+
+<p>Private Pubは通常の方法でインストールします。アプリケーションのgemfileにgemを追加して<code>bundle</code>コマンドを実行します。インストールをおこなうと、同時にFayeとその依存関係もインストールされます。</p>
+
+``` /Gemfile
+source 'http://rubygems.org'
+
+gem 'rails', '3.1.3'
+gem 'sqlite3'
+
+# Gems used only for assets and not required
+# in production environments by default.
+group :assets do
+ gem 'sass-rails', '~> 3.1.5'
+ gem 'coffee-rails', '~> 3.1.1'
+ gem 'uglifier', '>= 1.0.3'
+end
+
+gem 'jquery-rails'
+gem 'private_pub'
+```
+
+<p>次に以下のジェネレータを実行して、Fayeサーバを起動するのに必要な設定ファイルとRackupファイルを生成します。</p>
+
+``` terminal
+$ rails g private_pub:install
+ create config/private_pub.yml
+ create private_pub.ru
+```
+
+<p>以下のコマンドを実行してそのRackサーバを起動します。</p>
+
+``` terminal
+$ rackup private_pub.ru -s thin -E production
+>> Thin web server (v1.3.1 codename Triple Espresso)
+>> Maximum connections set to 1024
+>> Listening on 0.0.0.0:9292, CTRL+C to stop
+```
+
+<p>このコマンドは、本番稼働環境でFayeを動作させるのに必要なThinサーバを使ってFayeを起動します。最後にアプリケーションのJavaScript manifestファイルに<code>private_pub</code>を追加します。</p>
+
+``` /app/assets/javascripts/application.js
+// This is a manifest file that'll be compiled into including all the files listed below.
+// Add new JavaScript/Coffee code in separate files in this directory and they'll automatically
+// be included in the compiled file accessible from http://example.com/assets/application.js
+// It's not advisable to add code directly here, but if you do, it'll appear at the bottom of the
+// the compiled file.
+//
+//= require jquery
+//= require jquery_ujs
+//= require private_pub
+//= require_tree .
+```
+
+<p>もし対象のアプリケーションがRails 3.1よりも前のバーションを使用している場合、このJavaScriptファイルをlayoutファイルにインクルードします。</p>
+
+<h3>アプリケーションでPrivate Pubを使用する</h3>
+
+<p>Private Pubが設定できたら、簡単にチャンネルを購読してそのチャンネルに更新通知を発行することができます。必要な作業は、ビューテンプレート(例えば今回作成したメッセージを表示するページ)でチャンネルを購読するために、<code>subscribe_to</code>を呼び出してチャンネル名を渡すだけです。Fayeのチャンネルの形式はパスの表記に似ていて、ここでは<code>/messages/new</code>を使用します。</p>
+
+``` /app/views/messages/index.html.erb
+<h1>Chat</h1>
+
+<ul id="chat">
+ <%= render @messages %>
+</ul>
+
+<%= form_for Message.new, remote: true do |f| %>
+ <%= f.text_field :content %>
+ <%= f.submit "Send" %>
+<% end %>
+
+<%= subscribe_to "/messages/new" %>
+```
+
+<p>次にAJAXリクエストの結果として表示されるJavaScriptテンプレート(今回の例では新規のチャットメッセージを表示する部分)で、コードを<code>publish_to</code>ブロックでラップします。</p>
+
+``` /app/views/messages/create.js.erb
+<% publish_to "/messages/new" do %>
+ $("#chat").append("<%= j render(@message) %>");
+ $("#new_message")[0].reset();
+<% end %>
+```
+
+<p>これをおこなうことはつまり、このJavaScriptが元のリクエストをおこなったクライアントだけに返されるのではなく、購読しているすべてのクライアントの<code>/messages/new</code>チャンネルに配信されることを意味します。ではこれを試してみましょう。アプリケーションを2つの別々のブラウザで開き、片方でメッセージを入力すると、すぐにもう一方に表示されます。</p>
+
+<div class="imageWrapper">
+ <img src="http://asciicasts.com/system/photos/944/original/E316I02.png" width="851" height="418" alt="メッセージはすぐに全クライアントに表示される"/>
+</div>
+
+<p>つねにAJAXレスポンスから直接チャンネルに発行したいとは限りません。そうではなく例えばコントローラアクションから発行したい場合もあるでしょう。これをRubyコードのどこからでもおこなうことができます。<code>PrivatePub.publish_to</code>を使って、希望する発行先のチャンネル名とすべての購読しているクライアントで実行したいJavaScriptコードを渡します。これをアラートを返す方法で実際にやってみます。</p>
+
+``` /app/controllers/messages_controller.rb
+def create
+ @message = Message.create!(params[:message])
+ PrivatePub.publish_to("/messages/new", "alert('#{@message.content}');")
+end
+```
+
+<p>一つのブラウザでメッセージを入力すると、両方のブラウザでアラートが表示されます。</p>
+
+<div class="imageWrapper">
+ <img src="http://asciicasts.com/system/photos/945/original/E316I03.png" width="852" height="417" alt="アラートが両方のウィンドウで表示される"/>
+</div>
+
+<h3>JSONデータを扱う</h3>
+
+<p>JavaScriptコードではなくJSONデータを使った処理を好むならそれも可能です。その場合は文字列以外のオブジェクト(例えばハッシュ)を<code>publish_to</code>に渡すとJSONに変換されます。</p>
+
+``` /app/controllers/messages_controller.rb
+def create
+ @message = Message.create!(params[:message])
+ PrivatePub.publish_to("/messages/new", message: @message)
+end
+```
+
+<p>この方法をとる場合、返されるJSONを処理するために少しJavaScriptを書きます。これを<code>messages.js.coffee</code>に記述します。</p>
+
+``` /app/assets/javascripts/messages.js.coffee
+PrivatePub.subscribe "/messages/new", (data, channel) ->
+ alert data.message.content
+```
+
+<p>このファイルで<code>PrivatePub.subscribe</code>を呼び出します。これは引数にチャンネル名とコールバック関数(<code>data</code>と<code>channel</code>を引数にとる)をとります。このコールバックはチャンネルがJSONを受け取るたびに起動されます。我々のコードでは、返されたデータの<code>message.content</code>をただアラートで表示するだけです。ページをリロードして再度メッセージを入力すると、サーバから返されたJSONデータに基づくアラートが表示されます。</p>
+
+<div class="imageWrapper">
+ <img src="http://asciicasts.com/system/photos/946/original/E316I04.png" width="800" height="415" alt="JSONからのアラート"/>
+</div>
+
+<p>Private Pubを利用する一つの利点は、デフォルトでチャンネルがプライベートになることです。つまりユーザが明示的に購読していないチャンネルを受信してしますことを心配する必要がありません。これによって例えば、チャンネルを購読しているユーザだけがメッセージを読むことができる、プライベートなチャットルームを簡単に作成することができます。また一定期間後に購読を期限切れにすることで、ログアウト後にユーザから見えないようにできます。Private Pubを利用するRailsアプリケーションには<code>private_pub.yml</code>ファイルがあり、そこで設定をおこないます。</p>
+
+``` /config/private_pub.yml
+development:
+ server: "http://localhost:9292/faye"
+ secret_token: "secret"
+test:
+ server: "http://localhost:9292/faye"
+ secret_token: "secret"
+production:
+ server: "http://example.com/faye"
+ secret_token: "210eb617b6ce1c351d986a3185d34025cf42e5091a37502f18f595f7e8773853"
+ signature_expiration: 3600 # one hour
+```
View
4 episodes/318 - Upgrading to Rails 3.2/en.html
@@ -218,9 +218,9 @@
``` log
[ab939dfca5d57843ea4c695cab6f721d] [127.0.0.1]
-Started GET &quot;/&quot; for 127.0.0.1 at 2012-01-27 21:52:58 +0000
+Started GET "/" for 127.0.0.1 at 2012-01-27 21:52:58 +0000
[ab939dfca5d57843ea4c695cab6f721d] [127.0.0.1] Processing by ProductsController#index as HTML
-[ab939dfca5d57843ea4c695cab6f721d] [127.0.0.1] Product Load (0.3ms) SELECT &quot;products&quot;.* FROM &quot;products&quot;
+[ab939dfca5d57843ea4c695cab6f721d] [127.0.0.1] Product Load (0.3ms) SELECT "products".* FROM "products"
[ab939dfca5d57843ea4c695cab6f721d] [127.0.0.1] Rendered products/index.html.erb within layouts/application (22.0ms)
[ab939dfca5d57843ea4c695cab6f721d] [127.0.0.1] Completed 200 OK in 81ms (Views: 73.1ms | ActiveRecord: 0.3ms)
[98eec5f8976586c1165b981797086b6a] [127.0.0.1]
View
229 episodes/318 - Upgrading to Rails 3.2/ja.html
@@ -0,0 +1,229 @@
+<p>Rails 3.2がリリースされました。<a href="http://weblog.rubyonrails.org/2012/1/20/rails-3-2-0-faster-dev-mode-routing-explain-queries-tagged-logger-store">公式ブログ</a>に変更点のいくつかを説明した優れた記事が掲載されています。比較的重要な変更点として、開発モードで前回のリクエストから変更されたファイルのみをリロードするように変更されたことにより速度が向上しました。またJourneyというまったく新しいルーティングエンジンが採用され、より高速になりました。今回のエピソードでは、Rails 3.1のアプリケーションをRails 3.2にアップグレードする方法といくつかの新機能を紹介します。</p>
+
+<h3>アプリケーションのアップグレード</h3>
+
+<p>既存のRails 3.1のアプリケーションをRails 3.2にアップグレードするには、まずgemfileを修正します。</p>
+
+``` /Gemfile
+source 'http://rubygems.org'
+
+gem 'rails', '3.2.0'
+
+gem 'sqlite3'
+
+# Gems used only for assets and not required
+# in production environments by default.
+group :assets do
+ gem 'sass-rails', " ~> 3.2.3"
+ gem 'coffee-rails', "~> 3.2.1"
+ gem 'uglifier', '>=1.0.3'
+end
+
+gem 'jquery-rails'
+```
+
+<p>rails gemをversion <code>3.2.0</code>にアップグレードし、assets groupのgemのバージョン番号を修正して新規のRails 3.2アプリケーションで使用されているものと一致させます。すべてを最新バージョンにアップデートするために、<code>bundle update</code>を実行します。</p>
+
+<p>gemfileを修正するのに加えて、既存のアプリケーションを新規のRails 3.2アプリケーション相当に修正するために、いくつかの環境設定を変更します。開発モード用の設定ファイルに以下の行を追加します。</p>
+
+``` /config/environments/development.rb
+# Raise exception on mass assignment protection for Active Record models
+config.active_record.mass_assignment_sanitizer = :strict
+
+# Log the query plan for queries taking more than this (works
+# with SQLite, MySQL, and PostgreSQL)
+config.active_record.auto_explain_threshold_in_seconds = 0.5
+```
+
+<p>最初の行で<code>mass_assignment_sanitizer</code>を<code>:strict</code>に設定し、一括設定処理時に対象がそれを禁止している場合は例外を発生させます。2行目はauto-explainのしきい値を<code>0.5</code>に設定しています。これは、データベースへの問合せ処理に0.5秒以上かかる場合に、EXPLAINクエリが実行されてその結果がログに記録されます。<code>mass_assignment_sanitizer</code>オプションをテスト環境にもコピーして新規のRails 3.2アプリケーションに合わせ、またデフォルトで作成されなくなった以下の行を削除しておくのがいいでしょう。</p>
+
+``` /config/environments/test.rb
+# Allow pass debug_assets=true as a query parameter to load pages with unpackaged assets
+config.assets.allow_debugging = true
+```
+
+<h3>EXPLAINクエリ</h3>
+
+<p>アプリケーションがRails 3.2にアップグレードされたので、Railsコンソールで新機能のいくつかを紹介します。実行に時間がかかるデータベースクエリに対して自動的にEXPLAINクエリが実行されることはすでに説明しましたが、Active Recordクエリに対して<code>explain</code>を実行してコンソールから起動することもできます。</p>
+
+``` terminal
+1.9.2-p290 :001 > Product.order(:name).explain
+ Product Load (0.6ms) SELECT "products".* FROM "products" ORDER BY name
+ EXPLAIN (0.1ms) EXPLAIN QUERY PLAN SELECT "products".* FROM "products" ORDER BY name
+ => "EXPLAIN for: SELECT \"products\".* FROM \"products\" ORDER BY name\n0|0|0|SCAN TABLE products (~1000000 rows)\n0|0|0|USE TEMP B-TREE FOR ORDER BY\n"
+```
+
+<p><code>puts _</code>を使って、結果をより見やすい形で出力することができます。</p>
+
+``` terminal
+1.9.2-p290 :002 > puts _
+EXPLAIN for: SELECT "products".* FROM "products" ORDER BY name
+0|0|0|SCAN TABLE products (~1000000 rows)
+0|0|0|USE TEMP B-TREE FOR ORDER BY
+```
+
+<p>このEXPLAINクエリは簡単なクエリのためのものなのであまり面白くないですが、この機能は複雑なJOINクエリと共に利用されるときに非常に役に立ちます。アプリケーションの中で遅いデータベースクエリが実行される箇所がわかっていて、実行される度にEXPLAINクエリを生成させたくない場合は、そのクエリを以下のように<code>silence_auto_explain</code>ブロックでラップします。</p>
+
+``` terminal
+1.9.2-p290 :003 > ActiveRecord::Base.silence_auto_explain { Product.order(:name) }
+```
+
+<p>ブロック内のクエリはどれだけ実行に時間がかかってもEXPLAINクエリを生成しません。</p>
+
+<h3>新しいActiveRecordメソッド</h3>
+
+<p>Rails 3.2のもう一つの有用な新機能はpluckメソッドです。これを利用することで、列名を渡すとその列のすべての値が返されます。</p>
+
+``` terminal
+1.9.2-p290 :005 > Product.pluck(:name)
+ (0.2ms) SELECT name FROM "products"
+ => ["Settlers of Catan", "Flux Capacitor", "Technodrome", "Agricola", "Millennium Falcon", "Ryan's Cheesecake", "Answer to Everything"]
+```
+
+<p>これはどの列に対しても有効で、すべての値を適切なデータ型の配列として返します。</p>
+
+``` terminal
+1.9.2-p290 :007 > Product.pluck(:id)
+ (0.2ms) SELECT id FROM "products"
+ => [1, 2, 3, 4, 5, 6, 7]
+```
+
+<p>関連して、select節を用いて返される列を制限する場合は新たにuniqメソッドを利用できます。例えばこれを用いて、商品をユニークな名前ごとに一つずつ返すことができます。</p>
+
+``` terminal
+1.9.2-p290 :009 > Product.select(:name).uniq
+ Product Load (0.3ms) SELECT DISTINCT name FROM "products"
+ => [#<Product name: "Agricola">, #<Product name: "Answer to Everything">, #<Product name: "Flux Capacitor">, #<Product name: "Millennium Falcon">, #<Product name: "Ryan's Cheesecake">, #<Product name: "Settlers of Catan">, #<Product name: "Technodrome">]
+```
+
+<p>もう一つ関連した新機能であるfirst_or_createは<code>where</code>節と一緒に使われることを意図しています。</p>
+
+``` terminal
+1.9.2-p290 :010 > Product.where(name: "Foo").first_or_create!
+```
+
+<p>ここでは末尾に!をつけて、検証エラーがある場合には例外を発生させるようにしました。上のコードは<code>find_or_create_by_name</code>という記法で同じように動作します。初めて実行したときは(既存のレコードが存在しないと仮定して)その名前(<code>name</code>)で新規に<code>Product</code>を作成し、再度実行するとその条件に一致する商品を返します。この方法が優れているのは、次のように<code>create</code>の呼び出しに追加の属性を渡すことができるという点です。</p>
+
+``` terminal
+1.9.2-p290 :011 > Product.where(name: "Foo").first_or_create!(price: 5)
+```
+
+<p>新規に作成されたレコードはこれらの属性を継承しますが、<code>Product</code>を検索する場合にはその属性は考慮されません。</p>
+
+<p>最後に紹介する新しいメソッドは<code>safe_constantize</code>という名前で、文字列に対して呼び出せます。</p>
+
+``` terminal
+1.9.2-p290 :007 > "Product".safe_constantize
+ => Product(id: integer, name: string, price: decimal, description: text, discontinued: boolean, created_at: datetime, updated_at: datetime)
+```
+
+<p>これは一致する定数が存在する場合にそれを返します。これと通常の<code>constantize</code>メソッドとの違いは、一致する定数が見つからなかった場合に例外を発生させるのではなく<code>nil</code>を返すという点です。</p>
+
+<h3>マイグレーションの新機能</h3>
+
+<p>次にマイグレーションを生成するときに使うことができる新しいオプションを紹介します。例えば新規に<code>ProductVariation</code>モデルを作成するとしましょう。マイグレーションを次のように指定します。</p>
+
+``` terminal
+$ rails g model product_variation product_id:integer:index name 'price:decimal{7,2}'
+```
+
+<p>このマイグレーションは3つの新機能を使用しています。<code>ProductVariation</code>を<code>Product</code>に属する(belong to)よう定義したいので、列の一つを<code>product_id</code>と指定しました。Rails 3.2では3つ目の<code>index</code>オプションを指定すると、自動的に列に索引を付加します。</p>
+
+<p><code>ProductVariation</code>モデルに文字列の<code>name</code>という列を追加します。通常はこの場合マイグレーションで<code>name:string</code>と指定しますが、文字列(<code>string</code>)がデフォルトになったため列が文字列の場合はデータ型を指定する必要がなくなりました。最後に<code>decimal</code>(小数)フィールドを定義する場合、オプションを渡してそのデータ型の<code>precision</code>(数字全体の有効桁数)と<code>scale</code>(小数点以下の桁数)を指定できるようになりました。マイグレーションのこの部分は、シェルが修正しようと試みないように引用符で囲む必要があることに注意してください。</p>
+
+<p>生成されたマイグレーションは次のようになります。</p>
+
+``` /db/migrations/20120101000000_create_product_variations.rb
+class CreateProductVariations < ActiveRecord::Migration
+ def change
+ create_table :product_variations do |t|
+ t.integer :product_id
+ t.string :name
+ t.decimal :price, :precision => 7, :scale => 2
+
+ t.timestamps
+ end
+ add_index :product_variations, :product_id
+ end
+end
+```
+
+<p>このマイグレーションには指定したproduct_variationsがあり、その中で<code>product_id</code>フィールドは索引が定義され、<code>name</code>フィールドはデフォルトで<code>string</code>(文字列)になり、<code>price</code>フィールドは<code>precision</code>と<code>scale</code>のオプションが指定されています。</p>
+
+<p>ジェネレーターに関連して、新規にRailsアプリケーションを作成するときに常に指定するオプションがあるかも知れません。例えば、特定のデータベースを指定したり、ユニットテストを除外したりなどです。これらのオプションを、ホームディレクトリの<code>.railsrc</code>ファイルに保存することで、デフォルトに設定することができます。</p>
+
+``` terminal
+$ echo -d postgresql -T > ~/.railsrc
+```
+
+<p>これによって、新規にRailsアプリケーションを作成するときにこれらのオプションが自動的に付加されます。</p>
+
+``` terminal
+$ rails new blog
+Using -d postgresql -T from /Users/eifion/.railsrc
+```
+
+<h3>Key-Valueストア</h3>
+
+<p>ActiveRecordはモデルにおいて新しい方法でkey-valueストアを定義するようになりました。例えば<code>ProductVariation</code>モデルにおいて<code>colour</code>と<code>size</code>のような属性があるときに、それぞれに別々の列を作りたくないとします。その場合に新しい<code>store</code>メソッドを使ってこれらの値を一つの列に保存できます。</p>
+
+``` /app/models/product_variation.rb
+class ProductVariation < ActiveRecord::Base
+ store :properties, accessors: [:colour, :size]
+end
+```
+
+<p>ここで一つ目の引数は値が保存される列の名前で、二つ目では保存したい属性を定義しています。このデータベースの列を作成しなくてはいけないことには変わりがないので、マイグレーションが必要です。</p>
+
+``` terminal
+$ rails g migration add_properties_to_product_variations properties:text
+```
+
+<p>忘れずに<code>rake db:migrate</code>を実行してデータベースに列を追加します。</p>
+
+<p>これをコンソールで実際におこないます。新規に<code>ProductVariation</code>を作成し、通常の属性の場合と同じように<code>colour</code>と<code>size</code>の属性を設定します。</p>
+
+``` terminal
+Loading development environment (Rails 3.2.0)
+1.9.2-p290 :001 > p = ProductVariation.new(colour: 'blue', size: 3)
+ => #<ProductVariation id: nil, product_id: nil, name: nil, price: nil, created_at: nil, updated_at: nil, properties: {:colour=>"blue", :size=>3}>
+```
+
+<p>他の属性に対してと同じように、これらの属性にアクセスすることができます。</p>
+
+``` terminal
+1.9.2-p290 :003 > p.colour
+ => "blue"
+```
+
+<p><code>properties</code>ハッシュを介しても同じようにアクセスできます。</p>
+
+``` terminal
+1.9.2-p290 :004 > p.properties[:colour]
+ => "blue"
+```
+
+<p>これらの属性は実際のデータベース列ではないので、それらに対して検索をおこなうことはできませんが、属性のハッシュにアクセスする便利な方法です。</p>
+
+<h3>タグ付きログ</h3>
+
+<p>もう一つ、タグ付きログという機能を紹介します。これは通常は本番稼働環境で利用されるものですが、デモのために開発環境に追加してみます。そのために<code>log_tags</code>の設定オプションを指定し、 それを属性の配列に設定します。ここで属性はリクエストに対して呼び出されるメソッド名です。</p>
+
+``` /config/environments/development.rb
+config.log_tags = [:uuid, :remote_ip]
+```
+
+<p>Rails 3.2の新しいメソッドであるuuidはユニークなリクエストidを返すので、ログがどのリクエストからのものであるかを特定することができます。もう一つはリモートIPアドレスです。サーバを起動してリクエストを発行すると、ログの各行にはそれらの値がタグ付けされます。</p>
+
+``` log
+[ab939dfca5d57843ea4c695cab6f721d] [127.0.0.1]
+
+Started GET "/" for 127.0.0.1 at 2012-01-27 21:52:58 +0000
+[ab939dfca5d57843ea4c695cab6f721d] [127.0.0.1] Processing by ProductsController#index as HTML
+[ab939dfca5d57843ea4c695cab6f721d] [127.0.0.1] Product Load (0.3ms) SELECT "products".* FROM "products"
+[ab939dfca5d57843ea4c695cab6f721d] [127.0.0.1] Rendered products/index.html.erb within layouts/application (22.0ms)
+[ab939dfca5d57843ea4c695cab6f721d] [127.0.0.1] Completed 200 OK in 81ms (Views: 73.1ms | ActiveRecord: 0.3ms)
+[98eec5f8976586c1165b981797086b6a] [127.0.0.1]
+```
+
+<p>これは、本番環境で複数のRailsインスタンスがログファイルに書き込んでいる場合にとても便利です。これによって特定のリクエストに関連づけられたログのエントリーを識別できるようになります。</p>
Please sign in to comment.
Something went wrong with that request. Please try again.