rails:765
From: Hiroshi Takagi <gollum@h...>
Date: Sun, 11 Dec 2005 19:16:27 +0900
Subject: [rails:765] "version" は association 名に使えない?
高木宏です。 昨日の「Rails勉強会@大阪 第1回」のプレゼンの 「おまけ」でちょっと話題にした"version" 問題の詳細をレポートします。 rails (0.14.3), activerecord (1.13.0) で、 association 名に "version" という名称が使えなくなりました。 (rails (0.13.#) activerecord (1.11.1) では使えた。) 以下のようなケースです。 (ちょと、長いのですが、おつきあいを。) モデル Device ( devices テーブル), モデル Version ( versions テーブル)が以下のように定義されています。 mysql> desc versions; +-------+-------------+------+-----+---------+----------------+ | Field | Type | Null | Key | Default | Extra | +-------+-------------+------+-----+---------+----------------+ | id | int(11) | | PRI | NULL | auto_increment | | name | varchar(32) | | | | | +-------+-------------+------+-----+---------+----------------+ 2 rows in set (0.00 sec) mysql> desc devices; +---------------+-------------+------+-----+---------+----------------+ | Field | Type | Null | Key | Default | Extra | +---------------+-------------+------+-----+---------+----------------+ | id | int(11) | | PRI | NULL | auto_increment | | serial_number | varchar(32) | | | | | | version_id | int(11) | YES | | NULL | | +---------------+-------------+------+-----+---------+----------------+ 3 rows in set (0.01 sec) mysql> select * from versions; +----+-------------------+ | id | name | +----+-------------------+ | 1 | ver 1.0 | | 2 | ver 1.1 release 2 | | 3 | ver 2.0 alpha | +----+-------------------+ 3 rows in set (0.02 sec) mysql> select * from devices; +----+----------------+------------+ | id | serial_number | version_id | +----+----------------+------------+ | 1 | 00641220050011 | 2 | | 2 | 00641220050012 | 3 | +----+----------------+------------+ 2 rows in set (0.00 sec) mysql> モデル Device は、app/models/device.rb 中で、 version を 参照するよう定義しています。 class Device < ActiveRecord::Base belongs_to :version end この条件下で、以下のようなview を書きます。 <% for device in @devices %> <tr> <td><%=h device.serial_number %></td> <td><%=h device.version.name %></td> ....... 実行すると、 "undefined method `table_name' for ActiveRecord::Version:Module" というエラーがdevice.version.name のところで、raise します。 この AR::Version:Module とはなんじゃい? と、ごそごそしてみると、 {gems}/activerecord-1.13.0/lib/active_record/version.rb 中で、定義されているものでした。 module ActiveRecord module Version #:nodoc: MAJOR = 1 MINOR = 13 TINY = 0 STRING = [MAJOR, MINOR, TINY].join('.') end end バージョン番号を返すだけのモジュールじゃん... :-( このエラーが返るのは、Rails 環境下だけで、 AR を直接使って、 device.version.name を以下のようなスクリプトで参照するには、 まったく問題がありません。 #!/usr/bin/ruby require "rubygems" require_gem "activerecord" RAILS_ENV = 'development' RAILS_ROOT = "#{ENV['HOME']}/rails/trails" ActiveRecord::Base.configurations = File.open("#{RAILS_ROOT}/config/database.yml") {|f| YAML::load(f)} ActiveRecord::Base.establish_connection MODELS = RAILS_ROOT + "/app/models" $LOAD_PATH << MODELS require 'version' require 'device' Device.find(:all).each do |device| print device.serial_number, "\t" puts device.version.name end 実行すると、 00641220050011 ver 1.1 release 2 00641220050012 ver 2.0 alpha と、ちゃんと期待どおりの結果になります。 version.rb を削除したりrename してしまうと(下品!)、 rails サーバー上でも期待どおりに device.version.name がエラーを起さずに 使えますので、この新しい module に原因があるのは間違いないようです。 (version.rb は手元に残っているactiverecord では、1.11.1 にはありません でした。いつからはいったのか…。) Version という名前のクラスは、 今まで作成したrails アプリでかなり使っています。 急に使えなくなるとたいへん困るので、 なんとかまっとうに迂回する方法はないかと探しています。 コメントいただければさいわいです。 -- Hiroshi Takagi <gollum@h...> -- ML: rails@r... 使い方: http://QuickML.com/ Web Site: http://wiki.fdiary.net/rails/ ML Archives: http://www.fdiary.net/ml/rails/
-> 765 2005-12-11 11:16 [gollum@h... ] "version" は association 名に使えない? 766 2005-12-11 11:30 ┣[gollum@h... ] 767 2005-12-11 11:30 ┗[moriq@m... ] 768 2005-12-11 11:50 ┗[gollum@h... ]