Hatena::ブログ(Diary)

130単位

2013-10-15

Rails3.0 -> Rails3.2 アップグレード

今さら需要があるかわからない3.2へのアップグレード情報です。半年前にはほぼ準備完了していたんですが、諸事情あった末にようやく調整ができたので、先日アップグレードしました。ちなみにRails4リリース後のセキュリティメンテナンス対象は3.2系のみであるため、3.1系以前を運用されている方はできるだけアップグレードしたほうがいいと思います。

Gitのlogを見ながら書き起こしているため、エラーか非推奨警告かは曖昧な上に、もしかしたらバージョンアップ関係ない点もあるかもしれませんがご了承ください。

Gemfile

#gem 'rails', '~> 3.0'
gem 'rails', '~> 3.2'
#gem 'mysql2', '< 0.3'
gem 'mysql2'
gem 'devise-encryptable'
#gem 'jpmobile', '< 2.0'
gem 'jpmobile'
#gem 'spork', '> 0.9.0.rc'
#gem 'guard', '~> 0.8.8'
  • 古いバージョン指定を除外(コメントアウト分が3.0用)
  • DeviseでRestful Authentication互換のEncryptorを利用しているのでDevise Encyptable追加

Rails

rake rails:update
  • config以下が3.2のデフォルトで上書きされる
  • git diff で3.0の内容と比較しながら設定
config.assets.enabled = false
  • asset pipeline をオフにして3.0時代のasset管理を継続
has_many_association#clear
# has_many :posts
has_many :posts, :dependent => :delete_all
  • 3.0は @user.posts.clear = @user.posts.delete_all だった
  • 3.2は :dependent を指定しないと 関連idを NULL で UPDATE する
    • 関連idがNULL不可の場合、:dependent を :delete_all (または :destroy) にする
Rails.cache with specific instances
config.eager_load_paths += %W[#{config.root}/lib]
config.after_initialize do
  require_dependency 'my_class' unless defined? MyClass
end
MimeType
  • config/initializers/mime_types.rb でPDF追加してたけど不要になった

Gems

Devise
<%#= confirmation_url(@resource, :confirmation_token => @resource.confirmation_token) %>
<%= confirmation_url(@resource, :confirmation_token => @token) %>
#User.__send__(:generate_token, 'encrypted_password').slice(0, 8)
Devise.friendly_token.slice(0, 8)
  • ランダム文字列生成
RSpec(Guard)
#guard 'rspec', :version => 2, :cli => '--fail-fast --drb' do
guard 'rspec', :cli => '--fail-fast --drb' do
  • :version 指定不要
Capybara
  • git mv spec/requests spec/features
  • Capybara2系の仕様により、Capybara::DSL を使うspecをfeaturesへ移動
#select @datetime.month.to_s, :from => 'created_at_2i'
select "#{@datetime.month}", :from => 'created_at_2i'
#select @datetime.hour.to_s, :from => 'created_at_4i'
select '%02d' % @datetime.hour, :from => 'created_at_4i'
  • optionのテキスト検出が厳格になった
#click_button 'resource_submit'
click_button '登録する'
  • FormBuilder で submit の id が付かなくなった
Fabrication
  • resource!{ ... } -> resource{ ... }
  • sequence はブロック化して遅延評価
  • :from => Resource -> :class_name => :resource

感想

そもそもアップグレードが遅れたのは、非エンジニアがpublic以下を編集することが多いアプリで、asset pipeline対応ができなかったのが原因でした。ただ対応しないという判断で割り切ってしまえば、2系から3系よりは、対象項目が少なかった印象です。またテストを書いていたため、(テスト自体の修正もあったものの)比較的安心して進めることができました。Model.pluckが使えるようになったのが地味にうれしいですね。


4844331566
改訂新版 基礎Ruby on Rails (IMPRESS KISO SERIES)

関連記事

2012-12-24

デプロイ用gem CapistranoとMinaの比較

Capistrano

  • 多機能
  • capify -> cap setup -> cap deploy
  • Capfile, config/deploy.rb
  • バージョン管理しない共通ファイル/ディレクトリの管理に一工夫いる
    • symlinkを張るタスクを定義する必要あり
  • バージョン管理しない共通ファイル/ディレクトリは :shared_children 変数で管理できる
    • 2013/06/10追記:@さんご指摘ありがとうございます
  • git以外のSCMにも対応
  • remote-cache strategyは--recursiveなnon-bareリポジトリを保持
    • submodulesがあっても早い
    • scpによるstrategyもある
  • リリースパスにコピーしたあと.gitは消さない
  • リリースのバージョンはタイムスタンプ
  • capistrano-ext gem でマルチステージ対応
  • GitHubのヘルプにあるくらいデファクトともいえる

Mina

  • シンプル
  • mina init -> mina setup -> mina deploy
  • config/deploy.rb のみ
  • バージョン管理しない共通ファイル/ディレクトリの管理が楽
    • shared_paths にパスを配列で指定すれば良い
  • gitのみ対応
  • bareリポジトリを保持
    • submodulesがある場合時間がかかる
  • リリースパスにcloneしてから.gitを消す
  • リリースのバージョンは連番
  • マルチステージ非対応
  • フィリピン マニラ発プロダクト

Mina雑感

導入に関しては特に問題ありませんでした。Capistranoの経験があれば、デフォルトテンプレートを読めばほぼ理解できました。ただでかいsubmodule(WordPress)を含むリポジトリで試してみたのですが、デプロイの度にsubmoduleをcloneするので毎回時間がかかるのがいけてないところです(せっかくなのでPull Request送ってみました *1 )。良く言えば、まだまだこれから進化する余地のあるプロダクトといえます。

  • SCMgitでsubmoduleなし
  • プロジェクトが小規模でデプロイが本番のみ
  • 新しもの好き、Minaパッチを送って使いやすくしたい

このような条件/環境であれば、Minaを使ってみるのもいいかもしれません。そうでなければ、プロジェクト間の統一性の観点から、現状ではCapistranoを使っておいたほうが無難かと思います。

あわせて


4873114934
ウェブオペレーション ―サイト運用管理の実践テクニック (THEORY/IN/PRACTICE)

2011-12-23

ApacheとRailsのリダイレクト比較

PCサイトと携帯サイトを端末ごとに振り分けるのに、jpmobileの判定メソッドがお手軽なのでRailsのredirect_toを当初利用していました。が、おそらくApacheでリダイレクトさせたほうがパフォーマンスはいいはずです。ただ確信はなく、「推測するな、計測せよ」ということで調べてみました。

環境

Apache Bench

ab -n 100 -c 10 http://example.com/m/
結果サマリー
項目RailsApache
Requests per second63.3579.57
Time per request157.850125.677

というわけで単純な比較ではありますが、やはりApacheでリダイレクトしたほうが2割ほど速いようです。

Rails
Server Software:        Apache/2.2.16
Server Hostname:        example.com
Server Port:            80

Document Path:          /m/
Document Length:        96 bytes

Concurrency Level:      10
Time taken for tests:   1.578500 seconds
Complete requests:      100
Failed requests:        0
Write errors:           0
Non-2xx responses:      101
Total transferred:      54338 bytes
HTML transferred:       9696 bytes
Requests per second:    63.35 [#/sec] (mean)
Time per request:       157.850 [ms] (mean)
Time per request:       15.785 [ms] (mean, across all concurrent requests)
Transfer rate:          33.58 [Kbytes/sec] received

Connection Times (ms)
              min  mean[+/-sd] median   max
Connect:       10   61  48.7    101     119
Processing:    22   86  52.9    117     303
Waiting:       21   85  52.6    117     295
Total:         33  147 100.1    218     420

Percentage of the requests served within a certain time (ms)
  50%    218
  66%    230
  75%    237
  80%    239
  90%    251
  95%    263
  98%    274
  99%    420
 100%    420 (longest request)
Apache
Server Software:        Apache/2.2.16
Server Hostname:        example.com
Server Port:            80

Document Path:          /m/
Document Length:        302 bytes

Concurrency Level:      10
Time taken for tests:   1.256765 seconds
Complete requests:      100
Failed requests:        0
Write errors:           0
Non-2xx responses:      100
Total transferred:      52000 bytes
HTML transferred:       30200 bytes
Requests per second:    79.57 [#/sec] (mean)
Time per request:       125.677 [ms] (mean)
Time per request:       12.568 [ms] (mean, across all concurrent requests)
Transfer rate:          39.78 [Kbytes/sec] received

Connection Times (ms)
              min  mean[+/-sd] median   max
Connect:       10   57  49.5     13     122
Processing:    11   60  49.9     17     139
Waiting:       10   58  49.9     15     138
Total:         21  118  99.4     28     245

Percentage of the requests served within a certain time (ms)
  50%     28
  66%    212
  75%    218
  80%    221
  90%    235
  95%    242
  98%    244
  99%    245
 100%    245 (longest request)

レスポンスヘッダ

参考までにレスポンスヘッダも。Railsのほうはすこし付加されています。

Rails
Cache-Control:no-cache
Connection:close
Content-Length:96
Content-Type:text/html; charset=utf-8
Date:Fri, 23 Dec 2011 16:07:36 GMT
Location:http://example.com/
Server:Apache/2.2.16 (Amazon)
Status:302
X-Powered-By:Phusion Passenger (mod_rails/mod_rack) 3.0.7
X-Runtime:0.068700
X-UA-Compatible:IE=Edge,chrome=1
Apache
Connection:close
Content-Length:302
Content-Type:text/html; charset=iso-8859-1
Date:Fri, 23 Dec 2011 16:12:57 GMT
Location:http://example.com/
Server:Apache/2.2.16 (Amazon)

開発効率

サーバーとしてのパフォーマンスはApacheが優れていますが、開発も含めて考えると、Railsにも利点があります。まず、記述が簡潔かつ柔軟なこと。jpmobileの判定メソッドなら携帯キャリアを羅列する必要はありませんし、params[:controller]やparams[:action]を使ったりもできます。それから、テストがしやすいこと。他と同じようにRSpec/Capybaraのintegration testで書けるのは保守もしやすいのではないかと思います*1

ステータスコード

ちなみに、

デスクトップ用ページから従来のモバイル端末用ページにGooglebot-Mobileをリダイレクトするなら、301か302のどちらを使っても構わない

no title

とのことです。UAの条件のもとで恒久的なものなので、個人的には301かなと思う次第です。


4774142239
Apacheポケットリファレンス (POCKET REFERENCE)

関連記事

*1:Apacheでもできなくはないですが、外との通信となるためcapybara-webkitを使うなど工夫が必要です

2011-07-26

Rails3.1 Sass(SCSS)を使ってみたメモ

SassはCSSを簡潔かつ柔軟に記述するための記法で、SCSSはその派生でCSSとの互換性もある新しめな記法です。ともにセレクタをネストして記述できることがわかりやすい特徴のひとつです。

ソースを追ったわけではないので細かい動作まではわかりませんが、処理の流れや嵌りポイントなどはある程度把握できたのでそのメモです。

環境

  • Mac OS X 10.6.7
  • Ruby 1.9.2p290
  • Rails 3.1.0.rc5
  • Pow 0.3.1
  • sass 3.1.5
  • sass-rails 3.1.0.rc5

RailsでのSassコンパイルの仕組み

  • app/views/layouts/application.html.erb
  <%= stylesheet_link_tag    "application" %>
  • app/assets/stylesheets/application.css の5-6行目
 *= require_self
 *= require_tree .
  • この2行がトリガーとなってstylesheets以下のファイルがコンパイルされる
  • tmp/sass-cache以下にキャッシュされる
  • 最終的に1ファイルに結合して出力される
  • ブラウザから見たhtmlソース
    • development (config.action_controller.perform_caching = false)
<link href="/assets/application.css" media="screen" rel="stylesheet" type="text/css" /> 
    • production (config.action_controller.perform_caching = true)
<link href="/assets/application-ab401019e2cdd82e1a8f873003605a00.css" media="screen" rel="stylesheet" type="text/css" /> 

Sass(SCSS)利用時のポイント

  • rails new した時点で Gemfile に sass-rails が含まれている
  • rails generator では xxx.css.scss というファイル名で生成される
    • xxx.scss でもコンパイル対象になる
  • app/assets/stylesheets/application.css が肝
    • <%= stylesheet_link_tag "application" %>のままファイル消すと動かない
  • 最小ファイルでSCSS使いたければapplication(.css).scssに変更する
    • コメントにはスタイルのスコープ別にファイルを作成したほうがいいと書かれている
  • application.cssの先頭に @charset "utf-8"; を記述するとコンパイルが動作しない
  • コメントのあとに @charset "utf-8"; を記述する
    • するとコンパイル時に先頭に移動する
@charset "utf-8";/*
 * This is a manifest file that'll automatically include all the stylesheets available in this directory
 * and any sub-directories. You're free to add application-wide styles to this file and they'll appear at
 * the top of the compiled file, but it's generally better to create a new file per style scope.
*/
  • 結合順序はapplication.css、それ以外はファイル名順
    • *= require_ の行を入れ替えれば逆になる
    • リセットCSSを用いる場合は結合順序に注意してファイル名を工夫する
  • require filename として個別に書けばその順に結合される
  • .cssファイルもそのまま結合される
    • @import url('xxx.css'); を使う必要はない
    • ただしSCSS記法で記述してもコンパイルはされない
  • *= require_self の記述があるファイルを別につくるとエラーになる

Sprockets::CircularDependencyError in Users#index

Showing /path/to/app/views/layouts/index.html.erb where line #5 raised:

/path/to/app/assets/stylesheets/application.css has already been required

  • スタイルの変更反映はRailsの再起動必要
    • 開発段階では自動で再コンパイルしてほしい
    • 別のキャッシュのため「config.action_controller.perform_caching = true」してたのが原因
    • (上記の場合は) config.sass.cache の値などいじっても効果なし
    • 特にSCSSなど要コンパイルのAssetsを利用する開発時は perform_cashing = false にしたほうがいい
  • 再起動しまくっていたらPowが応答しなくなった(×2回)
    • Macbook再起動したら復活した

関連リンク

チュートリアル記事へのリンクです。文法も載っています。


4797363827
Rails3レシピブック 190の技

2010-12-13

WordPressでWebサイト制作ふりかえり

環境と体制

  • 専用サーバー
  • 本番環境と開発環境が同居
  • 静的ページ中心で約40ページ
  • 投稿を動的表示データのストアとして利用
  • テーマのデザイン/コーディングはコーダーさん
  • 運用中の本番反映もコーダーさん
  • サーバー環境構築と機能開発は自分

ふりかえり

ページ作成
  • テンプレート割り当て
    • page-[slugname].phpによる割り当て
      • ファイル先頭にページテンプレート専用の記述不要
      • ページ編集画面でテンプレート指定不要
      • ファイル一覧がサイト階層構造順には並ばないデメリット
  • コンテンツ
  • ヘッダー
    • 不本意ながらもページ毎に記述
      • スタイルの関係でページ種別により上位のセレクタを可変にしたいため
    • body_class()でのレイアウト判別はせず
      • ページIDによる判別しかできないため可読性が低い
      • そもそもPHPを理解していないと扱いづらそう
    • 逆にファイルのみでtitle,description,keywordのメンテが可能に
  • サイドバー
    • sidebar-[name].phpでファイル作成
    • get_sidebar([name])でページ種別に合わせて読み込み
  • フッター
    • Google Analyticsのタグ記述
    • 共通のヘッダーでHeadSpace2プラグインを使っていたらそちらでやってたかも
  • カスタムメニュー
    • 画像のメニューでもあったため利用せず
    • 頻繁にコンテンツが入れ替わるなら利用してもよいかも
  • 留意点
    • search,category,tag,authorというスラッグは1階層目には使えない
      • WordPressで予約されている文字列であるため
      • 1階層のみのページであれば問題ない
    • 別階層での同じページ名は使えない
      • 例えば/test/result/と/check/result/の同居は不可
      • サイト全体でスラッグがユニークである必要があるため
導入したプラグイン
  • Custom Field Gui Utility
    • カスタムフィールド拡張
  • Secure WordPress
  • WP Multibyte Patch
    • 日本語対応
  • オリジナル
    • リビジョン/自動投稿の制御、環境同期
試したプラグイン
  • W3 Total Cache
    • 確かに読み込み速くなりそう
    • 開発中に利用するとキャッシュが悪影響
    • 環境同期と相性わるい
    • 英語表記も重なって、システム慣れていないと利用難しい
  • CSV Importer
    • 複数ページの一括登録に有用
    • CSV読み込み箇所を日本語対応すれば使えなくはない

感想とまとめ

  • 動的生成コンテンツを含むならWordPressでサイト制作は悪くない選択
  • きれいなURLになるメリットもある
    • 設計時にスラッグの制約を考慮してURLの最下層はユニークにしておく
  • body_class()でIDでなくスラッグ出力してくれるといいと思う
  • 効率的に開発/運用するならPHPやサーバーの知識は必須
    • それが難しい体制であればある程度の妥協も必要
    • 編集の対象をファイル中心にした判断はよかったかも
  • 環境同期プラグインは運用コストが下がったと思われるので作ってよかった

4839935416
WordPress 3 サイト構築スタイルブック

488337730X
PHPによるWordPressカスタマイズブック―3.x対応


【関連記事】
WordPress サイト制作フロー 簡易まとめ - 130単位
条件付きでWordPressの環境同期できるプラグインを作ってみた - 130単位