前回の記事 で @udzura さんからalias_attribute
ならどうか、というコメントを頂いたのでこちらも試してみました。
1. self.primary_key = :legacy_idを入れる場合
こんな感じで、:idを:sushiとして定義。
class LegacyUser < ActiveRecord::Base establish_connection(:legacy) self.table_name = "hyper_legacy_tbl" self.primary_key = :legacy_id alias_attribute :sushi, :id end
結果、
[10] pry(main)> h = HyperLegacyTbl.first HyperLegacyTbl Load (0.3ms) SELECT `hyper_legacy_tbl`.* FROM `hyper_legacy_tbl` ORDER BY `hyper_legacy_tbl`.`legacy_id` ASC LIMIT 1 => #<HyperLegacyTbl legacy_id: 1, id: 100> [11] pry(main)> h.sushi => 1 [12] pry(main)> h.id => 1 [13] pry(main)> h.attributes["id"] => 100
ailias_attributesの時点ですでにid
はプライマリキーである"legacy_id"の方を向いている、ということ?
前回調べたとき、self.primary_key = :id
なら"id"カラムの方を向いてくれたのにこっちだとだめなのかよ。
2. self.primary_key = :legacy_id がない場合
class HyperLegacyTbl < ActiveRecord::Base establish_connection(:legacy) self.table_name = "hyper_legacy_tbl" alias_attribute :sushi, :id end
[1] pry(main)> h = HyperLegacyTbl.first HyperLegacyTbl Load (0.3ms) SELECT `hyper_legacy_tbl`.* FROM `hyper_legacy_tbl` ORDER BY `hyper_legacy_tbl`.`legacy_id` ASC LIMIT 1 => #<HyperLegacyTbl legacy_id: 1, id: 100> [2] pry(main)> h.id => 1 [3] pry(main)> h.sushi => 1 [4] pry(main)> h.attributes["id"] => 100
ぐぬぬ
3. トリッキーなことしてみる
class HyperLegacyTbl < ActiveRecord::Base establish_connection(:legacy) self.table_name = "hyper_legacy_tbl" self.primary_key = :id alias_attribute :sushi, :id self.primary_key = :legacy_id end
エイリアスするときの:id
はカラムの"id"を見てるはず
結果!
[1] pry(main)> h = HyperLegacyTbl.first HyperLegacyTbl Load (0.4ms) SELECT `hyper_legacy_tbl`.* FROM `hyper_legacy_tbl` ORDER BY `hyper_legacy_tbl`.`legacy_id` ASC LIMIT 1 => #<HyperLegacyTbl legacy_id: 1, id: 100> [2] pry(main)> h.sushi => 1 [3] pry(main)> h.id => 1 [4] pry(main)> h.attributes["id"] => 100
(´・ω・`)
4. self.primary_key = :id だけにしてみる
primary_keyを:id
だけにする
class HyperLegacyTbl < ActiveRecord::Base establish_connection(:legacy) self.table_name = "hyper_legacy_tbl" self.primary_key = :id alias_attribute :sushi, :id end
[1] pry(main)> h = HyperLegacyTbl.first HyperLegacyTbl Load (0.3ms) SELECT `hyper_legacy_tbl`.* FROM `hyper_legacy_tbl` ORDER BY `hyper_legacy_tbl`.`id` ASC LIMIT 1 => #<HyperLegacyTbl legacy_id: 1, id: 100> [2] pry(main)> h.sushi => 100 [3] pry(main)> h.id => 100 [4] pry(main)> h.legacy_id => 1
こうなるけど〜
[5] pry(main)> h.sushi = 1000 => 1000 [6] pry(main)> h.save (0.2ms) BEGIN SQL (0.3ms) UPDATE `hyper_legacy_tbl` SET `id` = 1000 WHERE `hyper_legacy_tbl`.`id` = 100 (0.2ms) COMMIT => true
update, deleteが危険な感じになるのは前回の記事と同じですね。(※id
は重複する可能性があります)
おまけ?
primary_key=
の動きでailias_attribute
の動きが変わるのか?と思って以下の処理を動かしてみました。HyperLegacyTblの実装は上の4と同じです。
[2] pry(main)> h.sushi => 1000 [3] pry(main)> HyperLegacyTbl.primary_key = :legacy_id => :legacy_id [4] pry(main)> h.sushi => 1000
後者の方の#sushi
はprimary_keyが変わったから:legacy_id
の値である"1"が返って来るんじゃないか、と思ったら違ったので予想外。
そして、
[6] pry(main)> h.id = 2000 => 2000 [7] pry(main)> h.save (0.2ms) BEGIN SQL (0.3ms) UPDATE `hyper_legacy_tbl` SET `id` = 1000 WHERE `hyper_legacy_tbl`.`legacy_id` = 1000 (0.2ms) COMMIT => true [8] pry(main)> HyperLegacyTbl.all HyperLegacyTbl Load (0.3ms) SELECT `hyper_legacy_tbl`.* FROM `hyper_legacy_tbl` => [#<HyperLegacyTbl legacy_id: 1, id: 1000>]
なんか発行されているSQLがいろいろおかしい。入力した2000はどこへ行ってもうたんや・・・。
この後もインスタンスはこう。
[9] pry(main)> h => #<HyperLegacyTbl legacy_id: 2000, id: 1000>
DBは発行されているSQLに従っているので当然こうですね。
mysql> select * from hyper_legacy_tbl; +-----------+------+ | legacy_id | id | +-----------+------+ | 1 | 1000 | +-----------+------+ 1 row in set (0.00 sec)
またポルナレフ状態になってきたwww