関連名を変える

概要

関連付けているテーブルから、関連するレコードを呼ぶ時にデフォルトだと

@member.member_image

のようになる。すごくださいし、ActiveRecordっぽくないので以下のように呼び出したい。

@member.image

時の備忘録。

環境

Rails 3.2.3
ruby 1.9.3p194 (2012-04-20 revision 35410) [x86_64-darwin11.3.0]
sqlite3 3.7.11 2012-03-20 11:35:50

モデル作成

[koji@koji-MacBook:~/rails/model_test] $ rails g model member name age
invoke active_record
create db/migrate/20120524125554_create_members.rb
create app/models/member.rb
invoke test_unit
create test/unit/member_test.rb
create test/fixtures/members.yml
[koji@koji-MacBook:~/rails/model_test] $ rails g model member_image name member:references
invoke active_record
create db/migrate/20120524125623_create_member_images.rb
create app/models/member_image.rb
invoke test_unit
create test/unit/member_image_test.rb
create test/fixtures/member_images.yml

マイグレーション

sqliteはmigrateをすると一緒にテーブルを作ってくれる。mysqlだとかはrake db:createの必要があるとか。

[koji@koji-MacBook:~/rails/model_test] $ rake db:migrate
== CreateMembers: migrating ==================================================

    • create_table(:members)

-> 0.0013s
== CreateMembers: migrated (0.0014s) =========================================

== CreateMemberImages: migrating =============================================

    • create_table(:member_images)

-> 0.0017s

    • add_index(:member_images, :member_id)

-> 0.0005s
== CreateMemberImages: migrated (0.0024s) ====================================

モデルを修正

memberモデルからmember_imageモデルを見えるようにする。

class Member < ActiveRecord::Base
  has_one :member_image
  attr_accessible :age, :name
end

member.member_imageで呼ぶテスト

1.9.3p194 :002 > ko = Member.create
(0.1ms) begin transaction
SQL (50.2ms) INSERT INTO "members" ("age", "created_at", "name", "updated_at") VALUES (?, ?, ?, ?) [["age", nil], ["created_at", Thu, 24 May 2012 13:03:10 UTC +00:00], ["name", nil], ["updated_at", Thu, 24 May 2012 13:03:10 UTC +00:00]]
(1.4ms) commit transaction
=> #
1.9.3p194 :003 > ko.member_image
MemberImage Load (0.2ms) SELECT "member_images".* FROM "member_images" WHERE "member_images"."member_id" = 1 LIMIT 1
=> nil

呼べてる。
本題である関連名を変える。

親モデルとなるMemberを修正

class Member < ActiveRecord::Base
  has_one :image, :class_name => "MemberImage"
  attr_accessible :age, :name     
end 

has_oneの引数には、呼びたい関連名を。class_nameにはモデル名(?)を与える。

member.imageで呼ぶ。

[koji@koji-MacBook:~/rails/model_test] $ rails c
Loading development environment (Rails 3.2.3)
1.9.3p194 :001 > ko = Member.create
(0.1ms) begin transaction
SQL (4.2ms) INSERT INTO "members" ("age", "created_at", "name", "updated_at") VALUES (?, ?, ?, ?) [["age", nil], ["created_at", Thu, 24 May 2012 13:07:11 UTC +00:00], ["name", nil], ["updated_at", Thu, 24 May 2012 13:07:11 UTC +00:00]]
(2.7ms) commit transaction
=> #
1.9.3p194 :002 > ko.image
MemberImage Load (0.1ms) SELECT "member_images".* FROM "member_images" WHERE "member_images"."member_id" = 3 LIMIT 1
=> nil
1.9.3p194 :003 >

おk。