query: tag:rails

 RSpecで現在時刻に関連するテストをするときに、Rails4.1からはTimecopを使わなくても ActiveSupport::Testing::TimeHelpers の to_travel というメソッドを使って現在時刻を設定することができます。

 たとえば、下記のように現在時刻を返すメソッドがあるとします。

ruby>>
class Foo
def now
Time.now
end
end
<<--

 正しく現在時刻を返しているかのテストは下記のように書けます。

ruby>>
travel_to Time.new(2014, 11, 24, 9, 30, 0) do
foo = Foo.new
expect(foo.now).to eq(Time.new(2014, 11, 24, 9, 30, 0))
end
<<--

 travel_toで現在時刻を設定しているので、expectで評価するときに決まった時間を書いて比較できます。

 ですがもしnowメソッドでDateTime.nowを返していると、to_travelでは対応できません。

ruby>>
class Foo
def now
DateTime.now # <- to_travelで設定した時間ではなく現在時刻が返る
end
end
<<--

 その場合にはやはりTimecopを使う必要があります。Gemfileには下記のようにgemを追加。

ruby>>
group :test do
gem 'timecop'
end
<<--

 テストは下記のように記述します。

ruby>>
Timecop.freeze(Time.new(2014, 11, 24, 9, 30, 0)) do
foo = Foo.new
expect(foo.now).to eq(Time.new(2014, 11, 24, 9, 30, 0))
end
<<--

 travel_to が対応しているのは Time.now と Date.today のみのようです。

 travel_to(date_or_time, &block)

 rails4.1からのtravel_toをrspecで使う

posted by akanuma akanuma on Tue 25 Nov 2014 at 00:03 with 0 comments

環境変数によってRailsアプリの動作を切り替えたいことがあって、

nginx + Passenger で動かしているRailsアプリに環境変数を渡す方法を調べました。

nginx の起動スクリプト(/etc/init.d/nginx)に書いても、

/etc/default/nginx に書いてもうまくいかなかったのですが、

nginx の設定ファイルの location ブロックで

passenger_set_cgi_param で設定することで環境変数が設定できます。

sh>>
passenger_set_cgi_param HOGE fuga;
<<--

これでRailsアプリの中で ENV['HOGE'] で "fuga" という値が取得できるように
なります。

参考ページ

16.3.5. Phusion Passengerが提供するアプリケーション

8.6.1. passenger_set_cgi_param

posted by akanuma akanuma on Sat 22 Nov 2014 at 14:14 with 0 comments
Rails4で入力フォームから日時を選択できるように datetimepicker を使ったのですがちゃんと動くまでに軽くはまったのでメモ。 [bootstrap3-datetimepicker-rails](https://github.com/TrevorS/bootstrap3-datetimepicker-rails) まずはGemfileに下記エントリを追加して bundle install ruby>> gem 'momentjs-rails' gem 'bootstrap3-datetimepicker-rails' <<-- moment と datetimepicker のJavaScriptファイルを読み込むための設定を追加します。 私は coffeescript を使っているので application.js.coffee に下記エントリ を追加します。 bootstrapの設定が入っていない場合はあわせて追加します。 js>> #= require bootstrap #= require moment #= require bootstrap-datetimepicker <<-- 続いてstylesheetの設定も追加します。 私の場合は scss を使っているので、application.css.scss に下記を追加。 ちなみに順番もこの通りじゃないとちゃんと動きません。 css>> @import "bootstrap-sprockets"; @import "bootstrap"; @import "bootstrap-datetimepicker"; <<-- ここまででひとまずの下準備は終了なので、実際にdatetimepickerを適用したい部分の作業をします。 今回の対象のView部分は下記のような感じです。 html>>
<%= f.text_field :start_datetime, value: @user.start_datetime, class: "form-control", id: "user_start_datetime" %>
<<-- f.text_field で出力される input タグに対して datetimepicker() メソッドを 実行します。 下記内容でcoffeescriptのファイルを別途作成して読み込みます。 js>> $ -> $('#user_start_datetime').datetimepicker() <<-- これで入力ボックスを選択した時に日時選択用のポップアップが表示されるようになります。 また、日付のフォーマットのデフォルトは MM/DD/YYYY hh:mm A/PM なので、日本の形式に変更します。 inputタグに data-date-format 属性で指定するのですが、rails の text_field タグでは追加の属性を指定できないため、先ほどのcoffeescriptを変更して動的に属性を追加します。 js>> $ -> date_format = {'data-date-format': 'YYYY/MM/DD HH:mm'} $('#user_start_datetime').attr(date_format) $('#user_start_datetime').datetimepicker() <<-- これで日付フォーマットが変更されます。 今回は一番シンプルな形で datetimepicker を使いましたが、オプションの指定で表示形式などは色々変更できますので、試してみてもらえると良いかと思います。 参考ページ [http://eonasdan.github.io/bootstrap-datetimepicker/](http://eonasdan.github.io/bootstrap-datetimepicker/)
posted by akanuma akanuma on Sat 22 Nov 2014 at 14:03 with 0 comments

 Passenger + Nginx でアプリケーションを起動しようとしたときに、下記のようなエラーが出ました。

sh>>
git://github.com/nzifnab/msgpack-rails.git (at master) is not checked out. Please run bundle install (Bundler::GitError)
<<--

 もちろん bundle install は実行済みです。msgpack-rails を使用するために、Gemfile に下記のような記述をしてあるのですが、色々調べたところ、Passenger が git からインストールした gem を認識してくれないようです。

ruby>>
gem 'msgpack-rails', :git => 'git://github.com/nzifnab/msgpack-rails.git'
<<--

 bundle install --deployment で解決するという情報も見つけたのですが、これは vendor ディレクトリにgemを持ってくるため結構な時間がかかります。デプロイでは世代管理していて、デプロイ時に新しいディレクトリを作成してデプロイしているので、開発環境のサーバへデプロイするたびに時間がかかるのはちょっと困るので他の方法を探したところ、bundle package
でOKという情報を見つけました。これはgemのキャッシュを vendor ディレクトリに持つもので、すぐに終わります。ただオプションで --all を指定しないと git 経由のgemをキャッシュしてくれないようです。

sh>>
bundle package --all
<<--

とすることで、git からの gem も見つけてくれるようになりました。

(参考サイト)deploying rails3 apps with bundler and phusion passenger: .bundle dir not found

posted by akanuma akanuma on Wed 25 Dec 2013 at 06:01 with 0 comments

 今まではネイティブのクライアントへJsonでレスポンスを返していたのですが、新しいサービスを開発する際に、レスポンスをMessagePackにしてはどうかとクライアントサイドから提案があったので検証してみました。

 ちなみにリクエストまでMessagePackにすると、リクエスト内容が簡単に参照できなくなってデバッグや問い合わせ時の調査が大変ということで、今回はレスポンスのみに使う想定です。

検証用アプリ


 構成は下記の通りです。

  • Nginx
  • Passenger
  • Ruby2.0
  • Rails4

 今回の検証はJson圧縮とMessagePack圧縮の比較です。アプリはRails4で実装します。また、JsonはデフォルトのJSONクラスよりもoj(Optimized JSON)が早いということなのでそちらを使用しています。MessagePackの方はMsgpackRailsを使います。Gemfileには下記を追加します。

(参考) JSONの替わりに使ったOJが速い
(参考) MsgpackRails

ruby>>
gem 'oj'
gem 'msgpack-rails', :git => 'git://github.com/nzifnab/msgpack-rails.git'
<<--

 Controllerは下記のように実装しました。

ruby>>
class StaticPagesController < ApplicationController

require 'oj'

after_action :testcompress

respond_to :json, :mpac

SERIALIZE_TEST_RESPONSE = {(省略)}

def serialize_test
respond_to do |format|
format.json { render :json => SERIALIZE_TEST_RESPONSE }
format.mpac { render :text => SERIALIZE_TEST_RESPONSE.to_msgpack, :content_type => 'application/x-mpac' }
end
end

def testcompress
response.body = ActiveSupport::Gzip.compress(response.body)
end

end
<<--

  • oj が追加されていると、MultiJSONによって自動的に oj が選択されるようです。
  • シリアライズするHashデータを SERIALIZE_TEST_RESPONSE として定義しておきます。
  • 処理内容としてはテスト用のデータをシリアライズして返すだけです。
  • また、今回はシリアライズ+圧縮を試すのですが、Rails側で圧縮した場合と、Nginxで圧縮した場合も比較してみます。Rails側で圧縮する場合の処理を testcompress メソッドに定義しておいて、after_action で gzip 処理を行います。Nginx側で圧縮する場合は after_action をコメントアウトします。

 検証方法としては、JMeterサーバを3つ用意して、100スレッドから上記APIへかけられるだけ負荷をかけてみるというやり方です。Nginxで圧縮するケースではHTTPヘッダマネージャでAccept-Encodingヘッダを設定する必要があります。また、Nginxの設定ファイルで下記の設定を有効にします。

sh>>
gzip_types text/plain text/css application/json application/x-javascript text/xml application/xml application/xml+rss text/javascript application/x-mpac;
<<--

 デフォルトでは application/x-mpac 以外が設定された状態でコメントアウトされていますので、コメントアウトを解除して application/x-mpac を追加してあります。

検証結果


検証結果は下記の通りです。

|caption=検証結果
|
|種別,圧縮,サンプル数,平均,中央値,90%LINE,最小値,最大値,スループット,KB/sec
|
|Json,Rails,48626,1816,1805,2002,25,2258,158.57,306.30
|MessagePack,Rails,271372,317,321,356,5,533,889.05,1701.66
|Json,Nginx,48824,1785,1775,1988,27,2206,159.11,393.07
|MessagePack,Nginx,333783,249,248,279,4,466,1093.61,2395.42
|MessagePack,非圧縮,346175,246,246,271,6,610,1134.33,19178.19

 Jsonの場合はCPUは常に振り切っている状態でしたが、MessagePackではCPUに余裕がありました。
 テスト結果のスループットとしてはMessagePack非圧縮のケースが一番速かったのですが、MessagePackのNginxでの圧縮の場合と大きな差はなく、実際のケースでは転送するデータ量を少なくすることによるメリットも大きいので、今回はMessagePackのNginx圧縮パターンを採用することにしました。

posted by akanuma akanuma on Sat 21 Dec 2013 at 19:00 with 0 comments

production環境などでログ自体を無効化するには
config/environments/production.rb あたりで

ruby>>
RAILS_DEFAULT_LOGGER = Logger.new("/dev/null")
<<--

すればok.

posted by genki genki on Sun 18 Dec 2011 at 08:43 with 0 comments

my.cnfの中で、clientとserver両方max_allowed_packet を適当に大きな数値に指定する。

pre>>
max_allowed_packet = 16M
<<--

config/database.yml でコネクション切断時に再接続する設定をする。

yaml>>
production:
reconnect: true
<<--

これで多分大丈夫。

posted by genki genki on Sat 11 Jun 2011 at 10:01 with 0 comments

昔は
mysql_retry_lost_connection
というものがあったのですが、最近 (Rails-2.3以降) は config/database.yml の中で

yaml>>
production:
reconnect: true
<<--

とやるだけで、接続が切れた場合に再接続してくれるようです。
まあ、ここまで用意するならデフォルトでそうなってても良いと思うんですけどね。

posted by genki genki on Sat 11 Jun 2011 at 07:03 with 0 comments

Rails-2.3.11用のExceptionNotificationプラグインは以下にあるようです (via
@a_matsuda

基本的にはこれを script/plugin install -r 2-3-stable
すれば良いのですが、ConsiderLocalの実装にバグがあるので
直す必要があります。

具体的には、以下のファイルの self.included の場所をConsiderLocalモジュールの直下に移動します。

あとはREADME通りに設定して、ConsiderLocalをApplicationControllerからincludeすればok

posted by genki genki on Sat 11 Jun 2011 at 06:46 with 0 comments

GitリポジトリのRailsプラグインをインストールするときに、
標準では master ブランチがインストールされますが、
特定のブランチの内容をインストールしたい場合には、以下のように -r オプションを使用します。

sh>>
script/plugin install --force https://github.com/rails/exception_notification.git -r 2-3-stable
<<--

上記の例では 2-3-stable ブランチをインストールします。

posted by genki genki on Sat 11 Jun 2011 at 05:18 with 0 comments

本日の午前中、比較的長期間当ブログにアクセス出来ない状態が発生しておりました。ご不便をおかけいたしましたことをお詫びいたします。

原因としては、Railsプロセスが暴走していたことが考えられます。
そのため、当blogで使用しているRailsのバージョンを 2.3.5から2.3.11に
アップグレードいたしました。
またしばらく様子を見て対応を考えます。

よろしくお願いいたします。

posted by genki genki on Sun 15 May 2011 at 04:35 with 0 comments

久々にRails関連の記事です。

vendor/gems 以下に gemをunpackしたときに、以下のような警告が出てくることがあります。

pre>>
Unpacked gem *** in vendor/gems has no specification file.
<<--

(***は適当なgemの名前)この場合、

pre>>
% cd vendor/gems/***
% gem specification *** > .specification
<<--

を実行すれば解決します。

posted by genki genki on Sun 7 Nov 2010 at 01:16 with 0 comments

現状

shell>>
% gem --version
1.3.6

% ./script/console
Loading development environment (Rails 2.2.2)
/usr/lib/ruby/gems/1.8/gems/rails-2.2.2/lib/rails/gem_dependency.rb:224:in specification':NoMethodError: undefined method version_requirements=' for #Gem::Dependency:0xb7769604
<<--

  • rails 側での対応はなし
  • rubygems 側は trunk で修正済
  • rubygems の新バージョンはなかなか出ず

対策

  • rubygems の trunk から最新版をインストールする (git じゃないのがダサイ)

インストール

(/tmp/ あたりの適当な場所で実行)

shell>>
% svn export http://rubygems.rubyforge.org/svn/trunk/ rubygems
A rubygems
A rubygems/History.txt
...
リビジョン 2460 をエクスポートしました。

% cd rubygems

ruby setup.rb

<<--

(setup.rb の実行でインストールされます。必要に応じてrootで)

確認

ruby>>
% ./script/console
Loading development environment (Rails 2.2.2)
/usr/lib/ruby/gems/1.8/gems/rails-2.2.2/lib/rails/gem_dependency.rb:224:Warning:...
/usr/lib/ruby/gems/1.8/gems/rails-2.2.2/lib/rails/gem_dependency.rb:224:Warning:...
...

User.count
=> 25707
<<--

warning が一杯出るが気にしない。
rubygems 1.3.7 が出るまで、とりあえずこれでOK。

posted by maiha maiha on Sun 7 Mar 2010 at 13:20 with 0 comments

Rails + Cucumber で Culerity を使うと、
以下のような WARNING が大量に発生する。
これでは、いくらテストがgreenでも精神はredになってしまう。

shell>>
% cucumber features/foo.feature
Using the default profile...
2010/01/20 18:43:57 com.gargoylesoftware.htmlunit.IncorrectnessListenerImpl notify
警告: Obsolete content type encountered: 'text/javascript'.
2010/01/20 18:43:58 com.gargoylesoftware.htmlunit.IncorrectnessListenerImpl notify
警告: Expected content type of 'application/javascript' or 'application/ecmascript' for remotely loaded JavaScript element at 'http://z-ecx.images-amazon.com/images/G/01/nav2/gamma/amazonJQ/amazonJQ-combined-core-5113._V228305908_.js', but got 'application/x-javascript'.
(...)
.

1 scenario (1 passed)
1 step (1 passed)
<<--

この警告メッセージは、 HtmlUnit が吐いているものであるが、
Culerity::RemoteBrowserProxy のオプション(log_level)
で制御することができる。
具体的には、
"script/generate culerity" を利用した場合、
以下の step ファイル内で定義されている。

shell>>
% vi features/step_definitions/culerity_steps.rb

  • $browser.log_level = :warning
  • $browser.log_level = :severe
    <<--

(celerity の default は :off だが、culerity が :warning にしている)

上記の修正によって、WARNING の表示が抑制される。

shell>>
% cucumber features/foo.feature
Using the default profile...
.

1 scenario (1 passed)
1 step (1 passed)
<<--

新規プロジェクトの度に毎回変更するのが面倒であれば、
generator の template を直接変更するのもいいかもしれない。

shell>>
% vi $GEM_PATH/gems/culerity-0.2.7/rails_generators/culerity/templates/features/step_definitions/culerity_steps.rb
<<--

指定可能な log_level は、
(高) :all, :severe, :warning, :info, :config, :fine, :finer, :finest, :off (低)
であり、実際に以下のコードで確認することができる。(JRuby)

ruby>>
% irb
irb(main):001:0> java.util.logging.Level.constants
=> ["FINE", "CONFIG", "FINEST", "FINER", "WARNING", "SEVERE", "OFF", "INFO", "ALL"]
<<--

log level に関するさらなる詳細は java.util.logging.Level を参照のこと。

http://java.sun.com/j2se/1.5.0/ja/docs/ja/api/java/util/logging/Level.html

posted by maiha maiha on Wed 20 Jan 2010 at 09:50 with 0 comments

(以下は PostgreSQL を例にしてますが、他のドライバでも通用すると思います)

install

まずは JRuby 用のドライバをインストールします。

shell>>
% gem install activerecord-jdbcpostgresql-adapter
<<--

設定

通常は database.yml に "adapter: jdbcpostgresql" と記述して利用するのですが、ここでは別の方法を紹介します。
内容は簡単で以下のコードを評価するだけです。

ruby>>
if RUBY_PLATFORM == "java"
require "active_record/connection_adapters/jdbcpostgresql_adapter"
end
<<--

(Railsであれば "config/initializers/jruby_compat.rb" などに記述しておくとよいでしょう)

メリット

  • MRI と同じアダプタ名 "postgresql" を利用できる
  • 変更なしで MRI, JRuby のどちらでも動作する

実行例

shell>>
% rvm use system
% ./script/console

User.count
=> 6

User.connection.class
=> ActiveRecord::ConnectionAdapters::PostgreSQLAdapter

% rvm use jruby
% ./script/console

User.count
=> 6

User.connection.class
=> ActiveRecord::ConnectionAdapters::JdbcAdapter
<<--

JRuby はまだ発展途上ですので、
開発や挙動確認で MRI を利用する局面が多々あります。
そんな折、この方法であればいちいち database.yml の内容を変更する必要がないため、非常にシームレス&快適に利用できると思います。

posted by maiha maiha on Mon 18 Jan 2010 at 23:16 with 0 comments

しばらくRails-2.3.2を使っていましたが、passengerのバージョンを上げてから微妙に不安定になった気がしたのでRails-2.3.5にアップデートしてみました。

今回は無変更でアップデートできました。

posted by genki genki on Wed 30 Dec 2009 at 06:45 with 0 comments
高井さんから献本いただきました。ありがとうございます。
エンタープライズ Rails
Dan Chak
オライリージャパン
売り上げランキング: 4228
第一章の冒頭でも触れられていますが、本書の対象読者はWebアプリケーションを作った事がある人が対象です。 * エンタープライズとは何か * 作ったWebサービスが流行ったらどうしたら良いのか * ActiveRecordが何をやっているかわからない 本書を読めば、このへんの疑問の答えが見つかると思います。 分量も300ページほどで読みやすく、 Railsで仕事をしている人にとっては必携だとおもいます。 Railsに関する他書と比べて、陳腐化しにくい内容を扱っているので、 お守り的に買っておいても良いと思います。 それにしても、表紙の生物が気になりますね。
posted by genki genki on Sat 15 Aug 2009 at 05:12 with 0 comments

最近はRailsあまり追いきれていない日比です。

ひょんなことから、AkitaOnRails@twitter(秋田さん)とtweetしていて、「Rails、日本でどうなの?」と質問を受けました。

秋田さんには以前ブログを読んで参考にさせていただいたことがあって、ちょっと感激なので、エントリにさせて頂きまっす。

秋田さんは日系三世なんだそうで、日本でのRailsの状況について興味をもたれているらしく、自身のブログでエントリで「日本でのRailsの状況」の情報提供を呼びかけておられます。Railsな方、ぜひぜひコメントくださいませー!

http://www.akitaonrails.com/2009/07/15/rails-developers-in-japan

AkitaOnRails.jpg

posted by satoko satoko on Sat 18 Jul 2009 at 16:15 with 0 comments

Cucumberのfeatureを実行すると、上記のエラーが出て困ったので探したら

I resolved it by uninstalling the old "bryanary-webrat" gem and making sure that "webrat" was up to date (0.4.3)

When you have both installed, ruby tends to load the old one instead.
http://groups.google.com/group/webrat/browse_thread/thread/d8ea685a1b1931a5#

古いwebrat gemを消しなさいと。

shell>>
gem search webrat

*** LOCAL GEMS ***

aslakhellesoy-webrat (0.3.2.2)
webrat (0.4.4, 0.4.3, 0.3.4)
<<--

案の定古いwebratがあったのでaslakhellesoy-webratをuninstallしたら動きました!

posted by satoko satoko on Tue 14 Apr 2009 at 15:15 with 0 comments

polymorphic_urlの中身で使われている build_named_route_callのソースを貼付けておきます。

ruby>>
def build_named_route_call(records, namespace, inflection, options = {})
unless records.is_a?(Array)
record = extract_record(records)
route = ''
else
record = records.pop
route = records.inject("") do |string, parent|
if parent.is_a?(Symbol) || parent.is_a?(String)
string << "#{parent}"
else
string << "#{RecordIdentifier.send("plural_class_name", parent
)}".singularize
string << "
"
end
end
end

    if record.is_a?(Symbol) || record.is_a?(String)
      route << "#{record}_"
    else
      route << "#{RecordIdentifier.__send__("plural_class_name", record)}"
      route = route.singularize if inflection == :singular
      route << "_"
    end

    action_prefix(options) + namespace + route + routing_type(options).to_s
  end

<<--

posted by genki genki on Wed 1 Apr 2009 at 13:13 with 0 comments

Railsでモデルのバージョン管理を行うというと、
acts_as_versionedを使うのが一般的でしたが、
しばらくメンテナンスされていないのと、githubでforkがカオス状態になっていて、公式ドキュメントと実装が一致しなくなっているなど、ちょっと使いにくい状況になっているようなので、それ以外の選択肢を調べてみました。

  • version_fu
    かなりシンプルな作り。ソースは100行程度。そのぶん、Versionedテーブルの作成などは自動でやってくれない。
  • SimplyVersioned こちらもシンプル路線。Versionedテーブルを使わずに、1つのテーブルでhas_manyアソシエーションを使って管理するタイプ。validates_uniqueness_ofとかを使っていないならこれでも良いかな。
  • acts_as_versioned_association
    aavでassociationを含むモデルのバージョニングが出来なかった問題を解決したものらしい。
posted by genki genki on Wed 1 Apr 2009 at 11:39 with 0 comments

s21gブログをRails-2.2.2からRails-2.3.2に対応させました。
主に以下のようなところで作業が発生しました。

  • session :off が不要になったので削除
  • application.rb ⇒ application_controller.rb
  • Test::Unit::TestCase から ActiveSupport::TestCaseに
    • test_helper.rbの中の定義もActiveSupport::TestCaseにする
  • formatted_xxx_url(:foo)をxxx_url(:format => :foo)に
posted by genki genki on Sat 28 Mar 2009 at 23:44 with 0 comments

Rails-2.2.2で動いているRailsアプリをRails-2.3.2に移行する場合、

pre>>
% rake rails:update
<<--

を行うと便利ですが、これを実行すると、以下のようなファイルが影響を受けます。

pre>>

Changed but not updated:

(use "git add/rm ..." to update what will be committed)

deleted: app/controllers/application.rb

modified: config/boot.rb

modified: config/environment.rb

modified: public/javascripts/controls.js

modified: public/javascripts/dragdrop.js

modified: public/javascripts/effects.js

modified: public/javascripts/prototype.js

Untracked files:

(use "git add ..." to include in what will be committed)

app/controllers/application_controller.rb

no changes added to commit (use "git add" and/or "git commit -a")
<<--

ApplicationControllerのファイル名が、application_controller.rbに変更になっています。一貫性を持たせるためでしょうね。

posted by genki genki on Sat 28 Mar 2009 at 20:43 with 0 comments

Passengerは非常に便利なのですが、
通常の設定では、アプリケーションへのアクセスが無い状態が5分程度続くと、プロセスがkillされてしまい、次回にアクセスする時に時間がかかるようになります。

これを回避するためには、httpd.confなどで、以下のように指定します。

pre>>
PassengerPoolIdleTime 0
<<--

これで、プロセス数の限界に達して追い出されるまで、Idle時間によってkillされる事は無くなります。

See Also

posted by genki genki on Sat 28 Mar 2009 at 20:32 with 0 comments

待っていたものが登場したようです。

**Rails Searchable API Doc **

ss

上記は
Rails-2.3.2のSearchable API Docです。
RailsのAPIを、class, method等を横断してLive Searchできるようです。

MerbのAPIドキュメント
と比べても、勝るとも劣らない仕上がりですね。
オフライン状態でも使えるようにダウンロードできるバージョンも用意されている模様。

posted by genki genki on Sat 28 Mar 2009 at 18:13 with 0 comments

会社設立以来ほとんど更新していなかったのですが、
iPhoneアプリ等の開発で製品を紹介するページを置く場所が必要になったので、
Rails-2.3.2がリリースされた事もあり、I18nを使って国際化仕様のサイトを作りました。

http://ja.www.s21g.com/ 日本語
ss1

http://en.www.s21g.com/ 英語
ss2

従来通り、http://www.s21g.com/にアクセスすると、ブラウザの設定に従って、自動的に日本語か英語のサイトに振り分けられます。
localizationファイルをもっと用意すれば、ISOで定義されてる言語なら何語でも大丈夫なのですが、とりあえずはjaとenのみサポートです。

I18nの使い方

ローカライズファイルは、デフォルトではconfig/locales/*.ymlに配置します。
mutohさんの、
locale
locale_rails
を使うと色々と便利です。
EdgeバージョンはRails-2.3.2でも利用出来ました。

自動的にロケールを判別するために、以下のようなコードを
ApplicationControllerに書きました。

ruby>>
class ApplicationController < ActionController::Base
before_filter :set_locale

(..snip..)

def set_locale
I18n.locale = @original_locale = fallback_locale(I18n.locale)
if request.host =~ /^([\w-]+).#{HOST.split(':')[0]}/i
I18n.locale = fallback_locale($1)
end
end

private
def fallback_locale(locale)
locale = locale.to_s
@available_locales ||= Set.new(I18n.available_locales)
until locale.empty? || @available_locales.include?(locale.intern)
locale = locale.split(/([-_])/)[0..-3].join
end
locale.present? ? locale.intern : I18n.default_locale
end
<<--

実際にローカライズする手順は、以下のような感じになります。

文字列のローカライズ

*.ymlファイルで定義されているメッセージキーに対して、

yaml>>
ja:
"hello": "こんにちわ"
<<--

こんな感じにt(...)ヘルパーメソッドを使います。

ruby>>
t("hello") #=> "こんにちわ"
<<--

時刻などのローカライズ

時刻の場合もほぼ同様で、以下のような*.ymlファイルで定義されている設定に対応して、

yaml>>
ja:
date:
formats:
default: "%Y/%m/%d"
short: "%m/%d"
long: "%Y年%m月%d日(%a)"
<<--

以下のようにl(...)ヘルパーメソッドを使ってローカライズします。

ruby>>
l(Date.today, :format => :short) #=> "03/22"
<<--

テンプレートのローカライズ

Viewテンプレートを丸ごとローカライズする場合は、

  • top/index.ja.html.erb
  • top/index.en.html.erb

のようなファイル名すればOKです。

posted by genki genki on Sun 22 Mar 2009 at 09:44 with 0 comments
UL/LIタグを使ってリストを表示するときに、 コレクションが空の場合はULタグを表示したくない場合というのが頻繁にあります。 html>> <% if @posts.present? %>
    <% @posts.each do |post| %>
  • <%= h(@post.body) %>
  • <% end %>
<% end %> <<-- そういう時は、だいたいこんな感じにコードを書きます。 しかし、条件が複雑になってきたり、複数のコレクションを考えなければ行けない場合に、きれいに記述出来なくなってきます。 そんな時は、以下のようなヘルパを使って、分岐条件を遅延評価するようにすると、処理が簡潔になります。 ruby>> module ApplicationHelper def delayed_if(&block) flag = Object.new def flag.set; @value = true end def flag.reset; @value = false end result = capture(&proc{block.call(flag)}) concat(result) if flag.instance_variable_get(:@value) end <<-- 利用法 html>> <% delayed_if do |flag| %>
    <% @posts.each do |post| %>
  • <%= h(@post.body) %>
  • <% flag.set %> <% end %>
<% end %> <<-- flag.setがよばれた時だけ、delayed_ifのブロックが表示されます。 この例だと単純すぎてあまり恩恵が分かりにくいですが、 複数のコレクションを一つのULで表示する場合などでも簡潔に記述出来るようになります。
posted by genki genki on Sat 21 Mar 2009 at 17:33 with 0 comments

リソースを新規に作成する場合に、既存のものを再利用して作成したい場合は良くあると思います。
そんな時は、newアクションで:idを受け取れるようにして、
以下のようにすると、簡単に実現出来ます。

ruby>>
def new
@post = Post.new
@post.attributes = Post.find(params[:id]).attributes if params[:id]
@posts = Post.for_user(current_user).all
end
<<--

そしてposts/new.html.erbの中で

html>>
<% if @posts.present? %>

method="GET"> <%= select_tag :id, options_for_select(@posts.map{|i| [i.title, i.id]}) %> <%= submit_tag '読み込む' %>
<% end %> <<--

こんな感じに、テンプレートの読み込みフォームを作ります。
これで完了です。
Ajaxで posts/new/1 のようなURLにGETで遷移するようにした方が格好がいいかもしれません。

newアクションが:idで指定したリソースをテンプレートとして利用して新規にリソースを作成するというのは、標準的な挙動になっても良い気がします。

posted by genki genki on Sat 21 Mar 2009 at 13:18 with 0 comments

久々にRailsモードが続いています。
APIを眺めていたら便利そうな機能を見つけたので紹介します。

layouts/application.html.erbの中などで、

html>>
<%= javascript_include_tag :defaults %>
<<--

のように書く事があると思いますが、この:defaults
というシンボルを指定することで、あらかじめ登録されている
expansionが展開されてincludeされます。
この:defaultsのようなものを自分で登録したい場合、

ruby>>
ActionView::Helpers::AssetTagHelper.register_javascript_expansion :foo => ["bar", "baz"]
<<--

のようにconfig/initializers/*あたりで登録しておけばOKです。
呼び出す時は

html>>
<%= javascript_include_tag :foo %>
<<--

でOK。プラグインを作るとき等に、複数のjsフィアルをまとめてincludeできるようにしておくと便利ですね。

スタイルシートの場合は、register_stylesheet_expansionという同様のメソッドを使います。

posted by genki genki on Thu 19 Mar 2009 at 10:58 with 0 comments

昨日の時点でTwitterでは話題になっていましたが、
正式にRails-2.3.2のリリースがアナウンスされたようです。

Rails 2.3: Templates, Engines, Rack, Metal, much more!

Rails 2.3 is finally done and out the door. This is one of the most substantial upgrades to Rails in a very long time.

今回のリリースの主な特徴は、

  • Templates: 自分好みのRailsアプリケーションのひな形を作る機能。
    沢山Railsアプリを作ってる人には便利そう。
  • Engines: Railsアプリをコンポーネント化して再利用する仕組み。MerbのSliceのような印象。render_componentが無くなったので、代わりにこれを使うと良いらしい。
  • Rack: Rackに対応。
  • Metal: 色々と省略して高速なレスポンスを実現する仕組み。
  • Nested forms: 頭痛への処方箋。かなり嬉しい。

全体的な印象として、Merb-1.1との差が少なくなってきた感じですね。
Rails-3(あるいはMerb-2)への道筋が見えてきた気がします。

See Also

posted by genki genki on Tue 17 Mar 2009 at 09:31 with 0 comments

Merbと違って、Railsには標準的なユーザ認証機構が用意されていないので、
昔から様々な認証用プラグインが乱立していました。
login_generator,
acts_as_authenticated,
restful_authentication,
restful_openid_authentication and so on...

今回は、@a_matsudaさんや
@lchinさんの勧めもあり、
比較的新しいClearanceという認証プラグインを試してみる事にしました。

インストール方法

config/environment.rbに

ruby>>
config.gem "thoughtbot-clearance",
:lib => 'clearance',
:source => 'http://gems.github.com',
:version => '>= 0.5.3'
<<--

config/environments/test.rbに

ruby>>
config.gem 'thoughtbot-shoulda',
:lib => 'shoulda',
:source => "http://gems.github.com",
:version => '>= 2.10.0'
config.gem 'thoughtbot-factory_girl',
:lib => 'factory_girl',
:source => "http://gems.github.com",
:version => '>= 1.2.0'
<<--

と記述し、

pre>>
% sudo rake gems:install
% sudo rake gems:install RAILS_ENV=test
<<--

あとは、

pre>>
% ./script/generate clearance
<<--

これでモデル、コントローラ、View、migrationファイルの作成が行われ、
マイグレーションの実行まで完了します。

続いて、config/environments/*.rb に、HOST="hostname"のようにホスト名を設定します。test, developmentでは"localhost"、
productionでは実際に使われるホスト名を指定すれば良いようです。
さらに、config/environment.rbの中で、

ruby>>
DO_NOT_REPLY = 'do_not_reply@s21g.com'
<<--

のように、アクティベーションメールの送信もとメールアドレスを設定します。

最後に、config/routes.rbの中で、何でも良いのでrootのNamedRouteを定義します。

ruby>>
map.root :controller => 'top'
<<--

以上で完了です。

追記

現時点でのバージョン(thoughtbot-clearance (0.5.3),
thoughtbot-factory_girl (1.2.0),
thoughtbot-shoulda (2.10.1))では、
clearanceに含まれているshoulda_macrosを手動でtest
ディレクトリの下にコピーする必要があるようです。

See Also

posted by genki genki on Mon 16 Mar 2009 at 16:13 with 0 comments
posted by genki genki on Sun 15 Mar 2009 at 23:56 with 0 comments

Rails向けのiPhoneサイト作成用プラグインのメモです。

See Also

posted by genki genki on Wed 11 Mar 2009 at 08:18 with 0 comments

ちまたで話題のCanonical URLですが、既存のRailsアプリケーションを
Canonical URLに対応させるためのプラグインを紹介します。

config/environment.rbの中で、以下の行を追加します。

ruby>>
config.gem 'mbleigh-canonical-url',
:lib => 'canonical_url',
:source => 'http://gems.github.com'
<<--

続いて、sudo rake gems:install
でGemをインストールします。
次に、ViewのHEADの中に以下の一行を追加します。

html>>
<%= canonical_link_tag %>
<<--

最後に、Controllerのshowアクションの中で、
respond_toやrenderの呼び出しより上に以下の一行を追加します。

ruby>>
canonical_url article_path(@article)
<<--

これはarticlesというリソースの例ですが、
実際のアプリケーションで使っているリソース名に置き換えてください。

これで完了。
Slagを使っていたりする場合に、Permalinkをcanonical urlとして指定したりするのが典型的な使い方になるのかな。

See Also

posted by genki genki on Sat 14 Feb 2009 at 22:40 with 0 comments

NetbeansのRails開発でデバッグしようとするとfast-debuggerをインストールしろと言われる。しかし最新版を入れるとエラーになってしまう。 ruby-debug-ideは0.4系が出ているが対応していないようだ。バージョン指定してインストールする必要がある。

ruby>>
$ sudo gem install ruby-debug-ide -v '= 0.3.1'
$ sudo gem install ruby-debug-base -v '= 0.10.2'
<<--

posted by ysakaki ysakaki on Sun 8 Feb 2009 at 02:50 with 0 comments

RailsのCacheSweeperは非常に便利なのですが、
callbackからコントローラのインスタンス変数にアクセスできると
もっと便利になる気がします。

ソースコードを読んでみたら、やっぱりみんなそう思うようで、
assignsメソッドが用意されていました。

rails>>
class PostsSweeper < ActionController::Caching::Sweeper
observe Post

def after_posts_rating
expire_fragment "posts/show/#{assigns(:post).id}"
end
end
<<--

こんな風に書けます。これは便利。

posted by genki genki on Thu 29 Jan 2009 at 06:03 with 0 comments

下記のページを参考にしました:
http://wiki.github.com/aslakhellesoy/cucumber/step-organisation

###モデル(テーブル)毎にstepsを作成する
原則はそれでいく、ただし認証などは別stepsとして作ったほうがベター:

  • employee_steps.rb
  • education_steps.rb
  • experience_steps.rb
  • authentication_steps.rb:認証用

all_steps.rbという巨大なファイルを作ることもできます。エレガントではないですけどね。

###モデルstepsには必ずGiven-When-Then stepを作る
モデルをカバーするようなstepsファイルでは、下記のCRUDをカバーするようなGiven-When-Then stepを書くことと。

  • 作成
  • 表示
  • 更新
  • 削除

###各stepsでは@variablesを作成して、オブジェクトの状態を保持できる
コントローラで取得する@userを下記のようなstepで記述できます:
rails>>
Give /^"(.*)"ユーザでログイン$/ do |login|
@user = User.find_by_login(login)
end
<<--
(注) 各stepで依存しあうことになり、再利用性が難しくなります
(注) 実際のログインシナリオはまた別にちゃんと記述する必要があります!

posted by satoko satoko on Fri 23 Jan 2009 at 15:42 with 0 comments

最近書いたNested Resourceに関する話題をまとめておきます。

外部サイトからのリンクバックもまとめ記事作成のための検索対象に含めたら、もっと便利になるかな。

posted by genki genki on Fri 23 Jan 2009 at 04:51 with 0 comments

変更点

  • (1) Rails2 の dirty column に対応
  • (2) 一括設定機能を追加

ruby>>
class User < ActiveRecord::Base
acts_as_bits :flags, %w( admin create read update delete )
end

user = User.new
user.admin = true # (1)
user.changed? # => true

user.flags = true # (2)
user.flags # => "11111"
<<--

インストール
shell>>
% gem install maiha-acts_as_bits --source=http://gems.github.com
<<--

posted by maiha maiha on Wed 21 Jan 2009 at 19:56 with 0 comments

まずはネストという言葉に関する定義の問題ですが、
諸橋さんが書いているように
、PostsコントローラはComments
コントローラを集約(aggregates)しますが、
内包(compose)する訳ではありません。

たとえば、管理画面に対応するAdminコントローラから、
Commentの削除や修正を行う場合に、AdminコントローラからCommentsコントローラを集約する事を考えると、その必要性が分かりやすいと思います。

PostsコントローラにCommentsを制御するコードを書いてしまう(内包してしまう)と、
Adminコントローラで同じ事をする必要が出来た場合に、
同じようなコードを書く必要が出てきます。

Don't Repeat Yourself!

結果として、メンテナンス性の悪いコードが出来上がります。
この事が、Postsコントローラの中でCommentsリソースを制御する
コードを書く事の問題の本質だと思います。
もちろん、あらかじめCommentsを集約する存在が
Postsしか無いと分かっている場合には問題ありません。

という事で、
続いて検索やCRUD以外の操作はどうするのかという問題について。

この問題を考えるための重要な視点として、最近のRailsやMerbでは、
リソースを制御するためのリソースコントローラと、
それ以外の制御をするための汎用コントローラの役割が分けて考えられるようになってきているという事があります。

上述の話の中で登場するコントローラを当てはめてみると、
以下のようになります。

|caption=コントローラの分類
|
|リソースコントローラ,汎用コントローラ
|
|Posts,Admin
|Comments,Dashboard

リソースコントローラとは、特定のモデルに対してCRUD(create, read, update, delete)操作を行う事に特化したコントローラです。

そう考えると、検索やCRUD以外の操作は、
汎用コントローラが行うのが自然な気がします。
例えば、ブログの記事(Posts)やコメント(Comments)
の検索を行う場合であれば、
SearchコントローラがPostsコントローラやCommentsコントローラ
を集約すればOK.
疑似コード的に表現すると、以下のような感じになります。

pre>>
Search#posts with_scope(query){ Posts#index }
Search#comments with_scope(query){ Comments#index }
<<--

この構造は2年ぐらい前にRailsで使ってみたのですが、
Railsのコントローラの実装がネストに向いていないので、
パフォーマンス上の問題に苦しみました。
Railsのコントローラは、フィルタの実行、アクションの実行だけでなく、レスポンスの作成を担っているので、ネストさせた場合に、
いったん作成したレスポンスを破棄する必要があるなど、無駄が大きいのです(Railsではお馴染みのDoubleRenderErrorが発生するのもこのせいです)

しかし今であれば、Merbを使う事によってこの問題は解決します。
Merbのコントローラはレスポンスの作成をする必要が無く、非常にシンプルなので、ネストさせてもパフォーマンスの問題はほとんどありません。

ということで、Merbを使えばみんなHappyになるよという話でした。

前回の記事の追補

前回の記事では、Aggregatorの#showで、POST, PUT, DELETEを
Aggregatedに委譲するという話を書きましたが、
例えばPostsコントローラがCommentsとTrackbacksの
2つのリソースを集約している場合に、
どちらのリソースに対する操作なのかを判別する方法を用意する必要があるので、どうやって実現するか書いておきます。

pre>>
posts/1 -> Posts#show
posts/1/comments -> Posts#show -> Comments
posts/1/trackbacks -> Posts#show -> Trackbacks
<<--

こんな感じに、posts/1/:resource に対するPOST, PUT, DELETEを、
:resourceに対応するリソースコントローラに委譲する感じですね。

posted by genki genki on Wed 21 Jan 2009 at 09:02 with 0 comments

ちょうどタイミング良く@maihaさんから、@yuguiさんが
近くに来てるという情報をもらったので、
@yamazさんも交えて、ネストしたリソースを扱うコントローラの問題の答えを得るべく、ミーティングをしました。

問題の定義:

モデル層で Post has_many Comment な関係にある時に、
Commentのリストとコメント投稿フォームを含むPosts#show画面(典型的な例としてはブログの一記事表示画面)から、Commentを投稿した場合に、

  1. Comments#createで受け取ると、Commentのsaveに失敗した時に、Post#showを表示したいが、redirect resource(@comment.post) すると、@comment.errorsの情報がロストしてしまう。
  2. Posts#create_commentなどで受け取ると、Commentリソースの処理をPostsコントローラで行う事になって責任の範囲が不明確になり、格好が悪い。

解決策

Merbベースでコンセプトを示します。
まずは、Postsコントローラの中で、以下のような包含関係を宣言するようにします。

ruby>>
class Posts < Application
has_many :comments
end

class Admin < Application
has_many :comments
end
<<--

これにより、コントローラ同士の協調関係を、コントローラ自身が知っているという事になります。
具体的にhas_manyがやることは、以下のようなbeforeフィルターをshowアクションに対してセットする事です。

ruby>>
class Posts < Application
before :only => :show do
controller = Comment.new(request)
@comment = case request.method
when "POST"; controller._dispatch(:create)
when "PUT"; controller._dispatch(:update)
when "DELETE"; controller._dispatch(:destroy)
end
end
<<--

:showアクションに対して、本来は使われない"POST", "PUT", "DELETE"
の各メソッドでのリクエストがあった場合に、Commentsコントローラに処理を回します。"GET"の場合は普通にPosts#showが行われます。
Commentsコントローラ側では、メソッドの返り値としてcommentオブジェクトを返します。

ruby>>
def create(comment)
Comment.create(comment)
end
<<--

作成に失敗した場合は、@comment.errorsにエラー情報が入っているので、
Posts#showの中から利用出来ます。

Posts#show内のComment投稿フォームは以下のような感じで、
Post#showに対してサブミットします。

html>>
<%= form_for @comment, :action => resource(@post) do %>
<%= partial "comments/form" %>
<% end =%>
<<--

コンセプトなので実際に動くかどうかまだ検証してないですが、
こんな感じで良いのではないかと。

MerbだとControllerがresponseの生成を担当していないので、
コントローラをまたいだ処理のネストが高速に行えます。
Railsの場合は、個々のアクションの実行がresponseの生成を伴うので、
この方法だとオーバヘッドが大きくて難しいかもしれません。

posted by genki genki on Tue 20 Jan 2009 at 02:03 with 0 comments

蛇足感がありますが、ちょっと補足しておきます。

Rails勉強会@東京、面白かったんですが。

そもそも何が問題かというと、
Commentsコントローラが担当すべきCommentリソースの処理を、
Postsコントローラで書かなきゃいけないのが格好わるいのでなんとかしたい、という事なんです。

Child belongs_to Parent な関係にあるChildリソースを描画する時は、
多くの場合Parentの描画を伴う事になるので、
そもそもControllerの仕組みが入れ子関係を上手く扱えるようになっているとありがたいのだけど。

View上で階層関係になっているものを、フラットなControllerで処理するという事がそもそも無理があるのかもしれない。
Controller側も階層化させるか、さもなくばセッション中に言ったように、
子供のリソースはAjaxで処理するという形にするのが奇麗かな。

posted by genki genki on Mon 19 Jan 2009 at 20:01 with 0 comments

[追記 2009.01.20]script/generate featureの項を追加

moroさんの記事を読んで、Cucumber wktk!と思っていたのでtry

http://d.hatena.ne.jp/moro/20081112/1226486135
http://d.hatena.ne.jp/moro/20081118/1226977015
http://gist.github.com/26024

こちらの導入手順を参考しました:
http://wiki.github.com/aslakhellesoy/cucumber/ruby-on-rails

###必要なgemをinstall

  • rspec
  • rspec-rails
  • cucumber
  • webrat

ローカルには0.1.15を入れたのですが、念のため0.1.13で依存しているというgem:aslakhellesoy-webratもinstallしました。

shell>>
gem sources -a http://gems.github.com
sudo gem install aslakhellesoy-webrat
<<--

###Webratを使うようにCucumberのenvに書く
${RAILS_ROOT}/features/support/env.rb

shell>>
require "webrat"
Webrat.configure do |config|
config.mode = :rails
end
<<--

###script/generate feature
moroさんところのcucumberの構造辺りで紹介されているgeneratorでfeatureやstepsを生成:

shell>>
$ ruby script/generate feature Product
<<--

###Webratの仕様が変わってた
moroさんのgistを下記に保存して使用し始めたのですが、
shell>>
${RAILS_ROOT}/features/step_definitions/webrat_ja_steps.rb
<<--

細かい仕様が変更されていました:
ディレクトリstep_definitionsの位置も変わっているのに加えて、visits => visit、fills_in => fill_inなどが変更されていました。ただ、前もって調べなくても、rake featuresすると仕様変更された旨のmessageが出るので安心です。

rails>>
visit home_path
fill_in "Email", :with => "good@example.com"
<<--

またpendingされたstepには、下記のようにsnippetsが出力されて便利だなぁと思いました:

shell>>
You can use these snippets to implement pending steps which have no step definition:
When /^パラメータを入力する product_comment[body]=dummy comment!$/ do
end
<<--

###Refs
http://moriq.tdiary.net/20081022.html
http://d.hatena.ne.jp/hs9587/20081231/1230691812
http://barkingiguana.com/2008/11/11/getting-started-with-story-driven-development-for-rails-with-cucumber

posted by satoko satoko on Mon 19 Jan 2009 at 15:44 with 0 comments

Merbの主要な開発者の一人であるwycats氏のgithub上のリポジトリに、
Rails3の元となるかもしれないコードがコミットされているようです。

ss

見慣れないciというディレクトリは、Continuous Integrationではないか(maiha談)とのこと。

Update

ActiveORM
なるものを見つけました。これは予想通り、AR, DM,
Sequelなどの共通基底となる何かでしょうか?

ruby>>
module ActiveORM
autoload :VERSION, 'active_orm/version'
autoload :Core, 'active_orm/core'

module Proxies
autoload :AbstractProxy, 'active_orm/proxies/abstract_proxy'
autoload :DataMapperProxy, 'active_orm/proxies/active_record_proxy'
autoload :DataMapperProxy, 'active_orm/proxies/datamapper_proxy'
autoload :SequelProxy, 'active_orm/proxies/sequel_proxy'
end

class << self
include Core::ClassMethods
end
end
<<--

これはBINGOっぽい。

See Also

posted by genki genki on Thu 15 Jan 2009 at 09:46 with 0 comments

毎回検索しているのでメモ。

rake db:fixtures:load FIXTURES=table1,table2 RAILS_ENV=test

posted by ysakaki ysakaki on Sat 3 Jan 2009 at 23:11 with 0 comments

以前、
benchmarkforrails
というRailsプラグインを紹介した事がありました。
しばらく互換性の問題があって使うのをやめていたのですが、
久々にRails-2.2.2環境で使ってみたら動いたので、
最新版のリポジトリの場所を紹介します。

gitで公開されているので、以下のようにインストールします。

pre>>
% ./script/plugin install git://github.com/cainlevy/benchmarkforrails.git
<<--

See Also

posted by genki genki on Fri 26 Dec 2008 at 14:20 with 0 comments

しばらくRails-2.0.2で運用しておりましたが、このたびRails-2.2.2対応にアップデートしました。

いくつか引っかかった所などをメモしておきます。

  • background_fuに手を入れたものを使っていたのですが、2.2.2で動かなかったので、最新のコードをgithubからpullしてmerge.
  • それでもsend!を呼び出してる所があって、エラーが出ていたので、sendを使うように書き換えた。
  • プラグイン版のjpmobileが残っていてエラーを出していたので、一旦外す。
  • erubisが以下のようなエラーを出すようになった。
    pre>>
    /opt/local/lib/ruby/gems/1.8/gems/erubis-2.6.2/lib/erubis/enhancer.rb:666:in `gsub!': can't modify frozen string (TypeError)
    <<--
  • TemplateHandler::Baseにcompileメソッドが必要になっていた
  • Rails-2.2.x対応版のprawntoを入れる。

ここまででテスト落ちずに全部実行できるようになった。

  • config/routes.rbの解釈が微妙に変わったせいでテストが通らなくなった所を、通るように修正。

だいたい以上で移行完了。

posted by genki genki on Fri 26 Dec 2008 at 02:18 with 0 comments
s21gブログをRails-2.2.2に移行する作業をしてる所なのですが、 erubis-2.6.2を使っていると、テスト時に以下のようなエラーが発生しました。 pre>> /opt/local/lib/ruby/gems/1.8/gems/erubis-2.6.2/lib/erubis/enhancer.rb:666:in `gsub!': can't modify frozen string (TypeError) <<-- erubisのソースを見てみると、 **lib/erubis/enhancer.rbL666** ruby>> def _add_text_to_str(str, text) return if !text || text.empty? text.gsub!(/['\#\\]/, '\\\\\&') str << text end <<-- となっていたので、これをひとまず以下のように直してみました(呼び出しもとをざっと見た感じだと、textを破壊的に変更しなくしても挙動に影響は無さそうだった)。 ruby>> def _add_text_to_str(str, text) return if !text || text.empty? text = text.gsub(/['\#\\]/, '\\\\\&') str << text end <<-- これで先ほどのエラーは出なくなったのですが、 今度は別なエラーが。 pre>> ActionView::TemplateError: You have a nil object when you didn't expect it! You might have expected an instance of Array. The error occurred while evaluating nil.<< On line #13 of app/views/users/edit.html.erb 10:
11:

Account

12: <% 13: form_for(:user, @user, 14: :url => user_path(@user), :html => {:method => :put}) do |f| 15: %> 16: <%= hidden_field_tag :from, :edit %> /opt/local/lib/ruby/gems/1.8/gems/actionpack-2.2.2/lib/action_view/helpers/text_helper.rb:42:in `concat' /opt/local/lib/ruby/gems/1.8/gems/actionpack-2.2.2/lib/action_view/helpers/form_helper.rb:252:in `form_for' <<-- form_forの中のconcatでエラーが出ている模様。こちらもソースを見てみると、 **actionpack-2.2.2/lib/action_view/helpers/text_helper.rb** ruby>> def concat(string, unused_binding = nil) if unused_binding ActiveSupport::Deprecation.warn("The binding argument of #concat is no longer needed. Please remove it from your views and helpers.", caller) end output_buffer << string end <<-- output_bufferがnilになってるって事みたいです。 Railsでerubisを使っている方、情報求む! **See Also** * [Using Erubis 2.6.2 with Rails 2.2.2 is incompatible?](http://stackoverflow.com/questions/389178/using-erubis-262-with-rails-222-is-incompatible) * [Rails 2.0.1 と 2.0.2 で ERB まわりがけっこう変更されてた](http://d.hatena.ne.jp/kwatch/20080501/1209657073)
posted by genki genki on Thu 25 Dec 2008 at 17:45 with 0 comments

何気なくTwitterのタイムラインを見ていたら、
wycatsとd2hがMerbがRails3にマージされるというお知らせをしてました。

Rails And Merb Merge

Today is a fairly momentous day in the history of Ruby web frameworks. You will probably find the news I’m about to share with you fairly shocking, but I will attempt to explain the situation.

Merb gets merged into Rails 3!

It’s christmas, baby, and do we have a present for you. We’re ending the bickering between Merb and Rails with a this bombshell: Merb is being merged into Rails 3!

確かに最近Railsが急速にMerb化してきてる気がするなと思ってたのですが。
save!のポリシーがどういう感じにmergeされるのかが気になる所。

Updates

#merbを見ていて分かった事など。

  • "any app can be a slice" 全てのアプリケーションがsliceとして利用可能らしい。てことはRails3にはsliceが入るっぽいですね。
  • "we're going to have a rails-core which is basically merb-core"
    merb-coreをベースとしてrails-coreを作るらしい。
  • "goal is beta by RailsConf" 次のRailsConfまでにβを出すのが目標。
  • "rails JS helpers become modular" RJSはモジュールかされて標準添付からは追い出される。
  • "DM definitely will be first-class. Just because AR is the default, doesn't mean DM shouldn't be just as easy to use."
    ARが標準のORMとなるが、DMも同等のサポートを受ける。
  • 依然としてtest/unitがデフォルト。これを機にRSpecが標準になったら良かったのだけど。
  • "get all the specific js code out of the view" JSはviewに書かないスタイルになる。
  • "Rails 3 will definitely have some incompatibilities with Rails 2.x" Rails 3が2.xとの互換性を保つのは難しそう。

全体的な印象として、MerbをベースにRailsを作り直す(%%ビッグバンリライトする%%→ビッグバンリライトではないと書いてた。notを読み落としてました。thanks @moro)ような感じがします。

See Also

posted by genki genki on Wed 24 Dec 2008 at 04:57 with 2 comments

WordPressとRailsを動かすためにMySQLとRuby/gem/Railsをインストールする。

mysql5のインストール

aptitude install mysql-server mysql-client libmysqlclient15-dev

aptitude install libmysql-ruby1.8

文字コードをUTF8に設定

/etc/mysql/my.cnf に下記内容を追記。

[client]

default-character-set=utf8

[mysqld]

default-character-set=utf8

/etc/init.d/mysql restart

mysql> status

でlatin1が混じっていないか確認する。

mysqladminのインストール

aptitude install mysql-admin

Ruby1.8.7インストール

aptitude install ruby1.8-dev ruby1.8 ri1.8 rdoc1.8 irb1.8 libreadline-ruby1.8 libruby1.8 libopenssl-ruby sqlite3 libsqlite3-ruby1.8

sudo ln -s /usr/bin/ruby1.8 /usr/bin/ruby

sudo ln -s /usr/bin/ri1.8 /usr/bin/ri

sudo ln -s /usr/bin/rdoc1.8 /usr/bin/rdoc

sudo ln -s /usr/bin/irb1.8 /usr/bin/irb

ruby -v

ruby 1.8.7 (2008-08-11 patchlevel 72) [x86_64-linux]

gem1.3.1のソースインストール

cd /usr/local/src/

wget http://rubyforge.org/frs/download.php/45905/rubygems-1.3.1.tgz

tar xvf rubygems-1.3.1.tgz

cd rubygems-1.3.1

ruby setup.rb

ln -s /usr/bin/gem1.8 /usr/bin/gem

gem -v

1.3.1

gem update

gem install rails

Railsのインストール

rails -v

Rails 2.2.2

ImageMagickのインストール

aptitude install imagemagick librmagick-ruby1.8 librmagick-ruby-doc libfreetype6-dev xml-core -y

aptitude install libmagick9-dev

export GEM_HOME=/var/lib/gems/1.8

export RUBY_LIB=/usr/lib

gem install rmagick

Successfully installed rmagick-2.8.0

posted by ysakaki ysakaki on Sun 14 Dec 2008 at 03:21 with 0 comments