トップ «前の日記(2005-03-16) 最新 次の日記(2005-03-20)» 編集

3 日坊主日記


2005-03-18 [長年日記]

_ [Rails] has_and_belongs_to_many な column の update

push_with_attributes な column を update する書き方がよくわからない。primary key を複合にしたのがまずいのかなあ。とりあえず ActiveRecord::Base.connection.execute して逃げてるけど要調査。

追記: ソースを読んでみた。対応していないように見える。

追記: Rails ML にも同じような質問がある。 その回答。なんじゃそりゃあ!!

追記: primary key については単一 (id) でも問題がある。collection<< で追加すると、なぜか id が association_id と同じ値になってしまう。そのため同じものを2回追加すると Duplicate entry... なエラーになる。

具体的には

 mysql> show create table rooms_users\G
 ...
 CREATE TABLE `rooms_users` (
   `room_id` int(10) unsigned NOT NULL default '0',
   `user_id` int(10) unsigned NOT NULL default '0',
   `_no` int(10) unsigned NOT NULL default '0',
   `id` int(10) unsigned NOT NULL auto_increment,
   PRIMARY KEY  (`id`)
 ) ENGINE=InnoDB DEFAULT CHARSET=sjis

こういう table があって

 class Room < ActiveRecord::Base
   belongs_to :school, :foreign_key => "school_id"
   has_and_belongs_to_many :users
   has_and_belongs_to_many :topics, :order=>"sent_on desc"
   has_many :user_histories, :order=>"create_on desc"

   def number=(number)
     write_attribute("_no", number)
   end

   def number
     read_attribute("_no").to_i
   end

   def school?
     false
   end
 end

 class User < ActiveRecord::Base
   has_and_belongs_to_many :rooms
   has_and_belongs_to_many :topics, :order=>"sent_on desc"
   has_many :user_histories

   def number=(number)
     write_attribute("_no", number)
   end

   def number
     read_attribute("_no").to_i
   end
 end

こうなっている。number (table では _no) の更新がここでの問題である。

 mysql> select * from rooms_users;
 +---------+---------+-----+----+
 | room_id | user_id | _no | id |
 +---------+---------+-----+----+
 |       2 |       4 |   0 |  1 |
 |       3 |       5 |   0 |  2 |
 |      13 |       3 |   5 |  3 |
 |      35 |       1 |   3 |  4 |
 +---------+---------+-----+----+
 4 rows in set (0.00 sec)

 C:\tmp\trunk\ptamt>ruby script/console development
 Loading development environment.
 irb(main):001:0> @room = Room.find(35)
 => ...
 irb(main):002:0> @user = User.find(1)
 => ...
 irb(main):005:0> @room.number=13
 => 13
 irb(main):008:0> @user.rooms<<@room

 mysql> select * from rooms_users;
 +---------+---------+-----+----+
 | room_id | user_id | _no | id |
 +---------+---------+-----+----+
 |       2 |       4 |   0 |  1 |
 |       3 |       5 |   0 |  2 |
 |      13 |       3 |   5 |  3 |
 |      35 |       1 |   3 |  4 |
 |      35 |       1 |  13 | 35 |  # id が妙だ
 +---------+---------+-----+----+
 5 rows in set (0.00 sec)

 C:\tmp\trunk\ptamt>ruby script/console development
 Loading development environment.
 irb(main):001:0> @room=Room.find(35)
 => ...
 irb(main):002:0> @user=User.find(1)
 => ...
 irb(main):003:0> @room.number=11
 => 11
 irb(main):004:0> @user.rooms<<@room
 ActiveRecord::StatementInvalid: #23000Duplicate entry '35' for key 1:
 INSERT INTO rooms_users (`_no`, `id`, `user_id`, `room_id`) VALUES (11, 35, '1', '35')

追記: 環境

 C:\tmp>ruby -v
 ruby 1.8.2 (2004-12-25) [i386-mswin32]

 C:\tmp>rake --version
 rake, version 0.4.15

 C:\tmp>gem -v
 0.8.8

 C:\tmp>gem list

 *** LOCAL GEMS ***

 actionmailer (0.7.1)
     Service layer for easy email delivery and testing.

 actionpack (1.5.1)
     Web-flow and rendering framework putting the VC in MVC.

 actionwebservice (0.6.0)
     Web service support for Action Pack.

 activerecord (1.8.0)
     Implements the ActiveRecord pattern for ORM.

 activesupport (1.0.1)
     Support and utility classes used by the Rails framework.

 cardinal (0.1.0)
     Ruby to Parrot compiler.

 creditcard (1.0)
     These functions tell you whether a credit card number is
     self-consistent using known algorithms for credit card numbers.

 rails (0.10.1)
     Web-application framework with template engine, control-flow layer,
     and ORM.

 rake (0.4.15)
     Ruby based make-like utility.

 rubygems-update (0.8.8)
     RubyGems Update GEM

 sources (0.0.1)
     This package provides download sources for remote gem installation

 vim-ruby (2004.09.20)
     Ruby configuration files for Vim.  Run 'vim-ruby-install.rb' to
     complete installation.

 C:\tmp>mysql -V
 mysql  Ver 14.7 Distrib 4.1.9, for Win95/Win98 (i32)

 C:\tmp>mysqld -V
 mysqld  Ver 4.1.9 for Win95/Win98 on i32 (Source distribution)

_ [Rails] has_and_belongs_to_many な column

has_and_belongs_to_many は habtm と略すらしい。

habtm な column は数値型でも文字列 (String) で返ってくるようだ (値の設定は数値でもいい)。これは結構はまる。

_ svn のログをSJISで書く

SET APR_ICONV_PATH=c:\arc\svn-win32-1.1.1\iconv
svn ci -m "..." --encoding shift_jis
[]