Ruby and Rails

Ruby と Ruby on Rails のこと

Rails のログから遅い処理を見つけるワンライナー

ログから 200ms 以上かかっている処理を見つけるワンライナー

$ ruby -ne 'if /(\d+\.?\d+)ms/ then puts "#{$.} #{$1} #{$_}" if $1.to_f > 200; end' log/production.log

行番号と時間とログが表示される。

283026 232.7 I, [2014-12-04T10:55:27.899449 #10715]  INFO -- :   Rendered foo/_form.html.erb (232.7ms)
283027 251.2 I, [2014-12-04T10:55:27.899779 #10715]  INFO -- :   Rendered foo/index.html.erb within laybars/slate (251.2ms)
283028 14459 I, [2014-12-04T10:55:27.901620 #10715]  INFO -- : Completed 200 OK in 14459ms (Views: 292.9ms | ActiveRecord: 12773.3ms)
283120 235.6 I, [2014-12-04T10:56:10.649837 #10715]  INFO -- :   Rendered foo/confirm.html.erb within laybars/slate (235.6ms)
283121 274 I, [2014-12-04T10:56:10.651312 #10715]  INFO -- : Completed 200 OK in 274ms (Views: 234.0ms | ActiveRecord: 20.7ms)
283364 6274 I, [2014-12-04T10:57:48.125014 #10715]  INFO -- : Completed 200 OK in 6274ms (Views: 8.6ms | ActiveRecord: 0.4ms)
283503 6309 I, [2014-12-04T10:59:24.549037 #10715]  INFO -- : Completed 200 OK in 6309ms (Views: 112.3ms | ActiveRecord: 6.4ms)
283686 333.6 I, [2014-12-04T11:02:31.107191 #28121]  INFO -- :   Rendered bar/_form.html.erb (333.6ms)
283687 335.7 I, [2014-12-04T11:02:31.107378 #28121]  INFO -- :   Rendered bar/index.html.erb within layouts/slate (335.7ms)
283688 596 I, [2014-12-04T11:02:31.324355 #28121]  INFO -- : Completed 200 OK in 596ms (Views: 547.1ms | ActiveRecord: 8.7ms)
283888 2456 I, [2014-12-04T11:03:41.131938 #28121]  INFO -- : Completed 200 OK in 2456ms (Views: 6.8ms | ActiveRecord: 2222.7ms)

該当行の前後を見たい場合。

# 100 行目を表示
$ sed -n 100p log/production.log

# 100 〜 200 行目を表示
$ sed -n 100,200p log/production.log

request-log-analyzer で Rails のログをレポーティング

wvanbergen/request-log-analyzer を使うと、Rails が吐き出すログからページの処理時間の平均や合計などのレポートを生成 ( 出力例 ) 。

インストール

$ gem install request-log-analyzer

簡単な使い方

$ request-log-analyzer log/production.log

オプション

--boring, -b

コンソールではカラフルな表示がデフォルト。そのため peco と組み合わせると都合が悪い。そういう場合は -b にするとエスケープシーケンスなしになる。

$ request-log-analyzer log/production.log -b | peco

--report-width

コンソールで実行すると、デフォルトでは画面いっぱいに表示される。

横長すぎるなら --report-width で横幅を指定。80 以下にするとデザインが狂うようだ。

$ request-log-analyzer log/development.log --report-width 80

--mail

logwatch のようにメールで送ってくれる。ちゃんと -b で、いい感じに --report-width されている。

$ request-log-analyzer log/development.log --mail test@example.com

フィルタリング

request-log-analyzer は指定日付以降や前、特定コントローラだけの表示が可能。

--after, --before

期間指定や、ある日付以降といった指定が可能。

$ request-log-analyzer log/development.log --after 2014-12-01

12月のみ。

$ request-log-analyzer log/development.log --after 2014-12-01 --before 2014-12-31

--select, --reject

特定コントローラだけ表示。

$ request-log-analyzer log/development.log* --select controller SomeController

さらに action で絞り込める。

$ request-log-analyzer log/development.log* --select controller SomeController --select action index

指定コントローラを除外。

$ request-log-analyzer log/development.log* --reject controller SomeController

フォーマット

request-log-analyzer は Rails ログ以外に --format を指定すれば下記ログにも対応。

例えば Apache

$ request-log-analyzer --apache-format combined access.log

フォーマット指定も可能。

$ request-log-analyzer --apache-format "%h %l %u %t \"%r\" %>s %b" access.log

詳しくは公式ドキュメント。

rails server

起動

rails s と短縮可能。

$ rails server

オプション

デフォルトの 3000 番ポートを 3001 番にする。

$ rails s -p 3001

デーモン化。

$ rails s -d

本番環境で動かすのなら。

$ rails s -e production

複数指定可能。

$ rails s -p 80 -d -e production

twitter-bootstrap-rails ではなく bootswatch-rails で Bootswatch を簡単に組み込む

maxim/bootswatch-rails を使うと Bootswatch を簡単に組み込むことができる。

もう一つの定番、twitter-bootstrap-rails よりテーマのダウンロードが不要だったりと楽。

Gemfile

Gemfile に下記を追加。

gem 'autoprefixer-rails'
gem 'bootstrap-sass'
gem 'bootswatch-rails'

インストール。

$ bundle

application.css.scss

bootswatch-rails は SCSS を使うため、既存の application.css を application.css.sccs に改名。

$ mv ./app/assets/stylesheets/application.css ./app/assets/stylesheets/application.css.scss

application.css.scss の変更は二点。

  1. 冒頭にある *= require_tree*= require_self は使わないので削除 ( あるとデザインが狂う )
  2. Bootswatch のテーマを記述 ( ここでは cosmo を利用 )
/*
(略)
  *= require_tree .  # 削除
  *= require_self    # 削除
  */

@import "bootswatch/cosmo/variables";

@import "bootstrap";

body { padding-top: 60px; }

@import "bootswatch/cosmo/bootswatch";

body { padding-top: 60px; } は Bootstrap の Navbar を使った時に、コンテンツが Navbar の下に隠れないようにする設定。

application.html.erb

./app/views/layouts/application.html.erb の yield を Bootstrap の container クラスで挟む。これでデザインが反映される。

  <div class="container">
<%= yield %>
  </div>

サーバの再起動

application.* 系のファイルは Rails サーバを再起動しないと反映されないので、再起動。

rails generate

rails generaterails g と短縮可能。

dry run

rails g-p ( --pretend ) を付けることで dry run 可能。

実際にファイルは作らないので、複数形だっけ?なんのファイル作るんだっけ?という時の確認に便利。

$  rails g controller Dashboard -p
      create  app/controllers/dashboard_controller.rb
      invoke  erb
      create    app/views/dashboard
      invoke  test_unit
      create    test/controllers/dashboard_controller_test.rb
      invoke  helper
      create    app/helpers/dashboard_helper.rb
      invoke    test_unit
      create      test/helpers/dashboard_helper_test.rb
      invoke  assets
      invoke    coffee
      create      app/assets/javascripts/dashboard.js.coffee
      invoke    scss
      create      app/assets/stylesheets/dashboard.css.scss

コントローラの作成

コントローラ名は基本は複数形。Dashboard のように単数形でも可。

コントローラ名を ProductCategories と CamelCase で指定すると product_categories_controller.rb になる。

$ rails g controller ProductCategories
      create  app/controllers/product_categories_controller.rb
      invoke  erb
      create    app/views/product_categories
      invoke  test_unit
      create    test/controllers/product_categories_controller_test.rb
      invoke  helper
      create    app/helpers/product_categories_helper.rb
      invoke    test_unit
      create      test/helpers/product_categories_helper_test.rb
      invoke  assets
      invoke    coffee
      create      app/assets/javascripts/product_categories.js.coffee
      invoke    scss
      create      app/assets/stylesheets/product_categories.css.scss

ビューも指定可能。

$ rails g controller Dashboard index edit show new
      create  app/controllers/dashboard_controller.rb
       route  get 'dashboard/new'
       route  get 'dashboard/show'
       route  get 'dashboard/edit'
       route  get 'dashboard/index'
      invoke  erb
      create    app/views/dashboard
      create    app/views/dashboard/index.html.erb
      create    app/views/dashboard/edit.html.erb
      create    app/views/dashboard/show.html.erb
      create    app/views/dashboard/new.html.erb
      invoke  test_unit
      create    test/controllers/dashboard_controller_test.rb
      invoke  helper
      create    app/helpers/dashboard_helper.rb
      invoke    test_unit
      create      test/helpers/dashboard_helper_test.rb
      invoke  assets
      invoke    coffee
      create      app/assets/javascripts/dashboard.js.coffee
      invoke    scss
      create      app/assets/stylesheets/dashboard.css.scss

モデルの作成

モデル名は単数形。

id, created_at, updated_at カラムは自動で作られる。

$ rails g model Product name:string quantity:integer product_category:references
      invoke  active_record
      create    db/migrate/20141203093915_create_products.rb
      create    app/models/product.rb
      invoke    test_unit
      create      test/models/product_test.rb
      create      test/fixtures/products.yml

カラムに指定できる型は下記。

  • binary
  • boolean
  • date
  • datetime
  • decimal
  • float
  • integer
  • primary_key
  • references
  • string
  • text
  • time
  • timestamp

references は関連を表す。

ProductCategory と Product があった場合に product_category:references すると、product.product_category_id カラムを作成し、INDEX も張ってくれる。

Scaffold の作成

コントローラもモデルもまとめて生成。/product_categories/ にアクセスすれば CRUD 機能も用意されている。

モデル名を指定する。

$ rails g scaffold ProductCategory name:string
      invoke  active_record
      create    db/migrate/20141203093952_create_product_categories.rb
      create    app/models/product_category.rb
      invoke    test_unit
      create      test/models/product_category_test.rb
      create      test/fixtures/product_categories.yml
      invoke  resource_route
       route    resources :product_categories
      invoke  scaffold_controller
      create    app/controllers/product_categories_controller.rb
      invoke    erb
      create      app/views/product_categories
      create      app/views/product_categories/index.html.erb
      create      app/views/product_categories/edit.html.erb
      create      app/views/product_categories/show.html.erb
      create      app/views/product_categories/new.html.erb
      create      app/views/product_categories/_form.html.erb
      invoke    test_unit
      create      test/controllers/product_categories_controller_test.rb
      invoke    helper
      create      app/helpers/product_categories_helper.rb
      invoke      test_unit
      create        test/helpers/product_categories_helper_test.rb
      invoke    jbuilder
      create      app/views/product_categories/index.json.jbuilder
      create      app/views/product_categories/show.json.jbuilder
      invoke  assets
      invoke    coffee
      create      app/assets/javascripts/product_categories.js.coffee
      invoke    scss
      create      app/assets/stylesheets/product_categories.css.scss
      invoke  scss
      create    app/assets/stylesheets/scaffolds.css.scss

rails g の取り消し

間違えて rails g したファイルを rails destroy で一括削除できる。rails d と短縮可能。

$ rails g controller ProductCategories
$ rails d controller ProductCategories
$ rails g model Product name:string quantity:integer
$ rails d model Product
$ rails g scaffold ProductCategory name:string
$ rails d scaffold ProductCategory

rails new

基本

$ rails new プロジェクト名

よく使う

$ rails new プロジェクト名 -d mysql -T
$ rails new プロジェクト名 --database=mysql --skip-test-unit

どちらも同じ意味。

-d では下記が指定可能。

バージョン指定

Rails 3.1.4 を使いたいなら。

$ rails _3.1.4_ new プロジェクト名

ヘルプ

$ rails new --help