This repository was archived by the owner on Jan 7, 2021. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathassociation_basics.html
2112 lines (1940 loc) · 113 KB
/
association_basics.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
<title>Ruby on Rails Guides: 활성 레코드관계(Active Record Association)에 대한 안내</title>
<link rel="stylesheet" type="text/css" href="stylesheets/style.css" />
<link rel="stylesheet" type="text/css" href="stylesheets/print.css" media="print" />
<link rel="stylesheet" type="text/css" href="stylesheets/syntaxhighlighter/shCore.css" />
<link rel="stylesheet" type="text/css" href="stylesheets/syntaxhighlighter/shThemeRailsGuides.css" />
</head>
<body class="guide">
<div id="topNav">
<div class="wrapper">
<strong>More at <a href="http://rubyonrails.org/">rubyonrails.org:</a> </strong>
<a href="http://rubyonrails.org/">Overview</a> |
<a href="http://rubyonrails.org/download">Download</a> |
<a href="http://rubyonrails.org/deploy">Deploy</a> |
<a href="http://rails.lighthouseapp.com/projects/8994-ruby-on-rails/overview">Code</a> |
<a href="http://rubyonrails.org/screencasts">Screencasts</a> |
<a href="http://rubyonrails.org/documentation">Documentation</a> |
<a href="http://rubyonrails.org/ecosystem">Ecosystem</a> |
<a href="http://rubyonrails.org/community">Community</a> |
<a href="http://weblog.rubyonrails.org/">Blog</a>
</div>
</div>
<div id="header">
<div class="wrapper clearfix">
<h1><a href="index.html" title="Return to home page">Guides.rubyonrails.org</a></h1>
<p class="hide"><a href="#mainCol">Skip navigation</a>.</p>
<ul class="nav">
<li><a href="index.html">홈</a></li>
<li class="index"><a href="index.html" onclick="guideMenu(); return false;" id="guidesMenu">목차</a>
<div id="guides" class="clearfix" style="display: none;">
<hr />
<dl class="L">
<dt>시작</dt>
<dd><a href="getting_started.html">레일즈 시작하기</a></dd>
<dt>모델(Models)</dt>
<dd><a href="migrations.html">레일즈 데이터베이스 마이그레이션</a></dd>
<dd><a href="active_record_validations_callbacks.html">액티브 레코드 데이터 검증(Validation)과 Callback(콜백)</a></dd>
<dd><a href="association_basics.html">액티브 레코드 Association(관계)</a></dd>
<dd><a href="active_record_querying.html">액티브 레코드 쿼리 인터페이스</a></dd>
<dt>뷰(Views)</dt>
<dd><a href="layouts_and_rendering.html">레이아웃(Layouts)과 렌더링(Rendering)</a></dd>
<dd><a href="form_helpers.html">액션 뷰 폼 핼퍼(Action View Form Helpers)</a></dd>
<dt>컨트롤러(Controllers)</dt>
<dd><a href="action_controller_overview.html">액션 컨트롤러 둘러보기</a></dd>
<dd><a href="routing.html">외부 요청에 대한 레일즈 라우팅</a></dd>
</dl>
<dl class="R">
<dt>심화내용</dt>
<dd><a href="active_support_core_extensions.html">액티브 서포트(Active Support) 확장(Core Extensions)</a></dd>
<dd><a href="i18n.html">레일즈 국제화I(nternationalization) API</a></dd>
<dd><a href="action_mailer_basics.html">액션 메일러의 기본</a></dd>
<dd><a href="testing.html">레일즈 어플리케이션 테스트하기</a></dd>
<dd><a href="security.html">레일즈 어플리케이션의 보안</a></dd>
<dd><a href="debugging_rails_applications.html">레일즈 어플리케이션 디버깅</a></dd>
<dd><a href="performance_testing.html">레일즈 어플리케이션 성능 테스트하기</a></dd>
<dd><a href="configuring.html">레일즈 어플리케이션 설정</a></dd>
<dd><a href="command_line.html">레일즈 커멘드라인 도구와 Rake 테스크</a></dd>
<dd><a href="caching_with_rails.html">레일즈를 이용한 캐싱</a></dd>
<dt>레일즈 확장하기(Extending Rails)</dt>
<dd><a href="plugins.html">레일즈 플러그인 작성의 기본</a></dd>
<dd><a href="rails_on_rack.html">렉 위의 레일즈(Rails on Rack)</a></dd>
<dd><a href="generators.html">레일즈 제너레이터(Generator) 제작과 수정</a></dd>
<dt>루비 온 레이즈에 기여하기</dt>
<dd><a href="contributing_to_ruby_on_rails.html">루비 온 레이즈에 기여하기</a></dd>
<dd><a href="api_documentation_guidelines.html">API 문서 가이드라인</a></dd>
<dd><a href="ruby_on_rails_guides_guidelines.html">루비 온 레일즈 가이드에 대한 가이드라인</a></dd>
<dt>Release Notes</dt>
<dd><a href="3_0_release_notes.html">Ruby on Rails 3.0 Release Notes</a></dd>
<dd><a href="2_3_release_notes.html">Ruby on Rails 2.3 Release Notes</a></dd>
<dd><a href="2_2_release_notes.html">Ruby on Rails 2.2 Release Notes</a></dd>
</dl>
</div>
</li>
<li><a href="contribute.html">기여하기</a></li>
<li><a href="credits.html">수고하신 분들</a></li>
</ul>
</div>
</div>
<hr class="hide" />
<div id="feature">
<div class="wrapper">
<h2>활성 레코드관계(Active Record Association)에 대한 안내</h2>
<p>본 안내문서는 액티브 레코드의 여러가지 관계(associations) 특성들을 다루고 있습니다. 이 문서의 참고를 통해서 당신은</p>
<ul>
<li>활성 레코드 모델들 간의 관계 선언</li>
<li>활성 레코드 관계들의 여러가지 형태에 대한 이해</li>
<li>관계 생성을 통한 추가된 모델 함수 및 데이터의 사용
등을 하실 수 있게 될 것입니다.</li>
</ul>
<div id="subCol">
<h3 class="chapter"><img src="images/chapters_icon.gif" alt="" />Chapters</h3>
<ol class="chapters">
<li><a href="#">왜 ``관계’’인가?</a></li><li><a href="#">관계의 유형들</a><ul><li><a href="#belongs_to"><tt>belongs_to</tt> 관련</a></li> <li><a href="#has_one"><tt>has_one</tt> 관련</a></li> <li><a href="#has_many"><tt>has_many</tt> 관련</a></li> <li><a href="#has_many-through"><tt>has_many : through</tt> 관계</a></li> <li><a href="#has_one-through"><tt>has_one :through</tt> 관련</a></li> <li><a href="#has_and_belongs_to_many"><tt>has_and_belongs_to_many</tt> 관련</a></li> <li><a href="#belongs_to-has_one"><tt>belongs_to</tt> 와 <tt>has_one</tt> 의 선택</a></li> <li><a href="#has_many-through-has_and_belongs_to_many"><tt>has_many :through</tt> 와 <tt>has_and_belongs_to_many</tt> 의 선택</a></li> <li><a href="#polymorphic">폴리모픽(polymorphic: 다중) 관계</a></li> <li><a href="#">자체 연결</a></li></ul></li><li><a href="#">팁, 묘수, 그리고 경고</a><ul><li><a href="#">케쉬 제어하기</a></li> <li><a href="#">이름 충돌 피하기</a></li> <li><a href="#">스키마 갱신하기</a></li> <li><a href="#">관계 범위 제어하기</a></li></ul></li><li><a href="#">자세한 관계 참고자료</a><ul><li><a href="#belongs_to"><tt>belongs_to</tt> 관계 참고자료</a></li> <li><a href="#has_one-association-reference"><tt>has_one</tt> Association Reference</a></li> <li><a href="#has_many-association-reference"><tt>has_many</tt> Association Reference</a></li> <li><a href="#has_and_belongs_to_many-association-reference"><tt>has_and_belongs_to_many</tt> Association Reference</a></li> <li><a href="#association-callbacks">Association Callbacks</a></li> <li><a href="#association-extensions">Association Extensions</a></li></ul></li><li><a href="#changelog">Changelog</a></li></ol></div>
</div>
</div>
<div id="container">
<div class="wrapper">
<div id="mainCol">
<p>h3(#). 1 왜 ``관계’’인가?</p>
<p>왜 우린 모델들사이에 관계가 필요한 것일까요? 그것은 관계가 연결된 모델들을 보다 간단하고 쉽게 동시에 처리를 해주기 때문입니다. 예를 들어서 간단한 레일즈 응용프로그램이 고객모델과 주문모델을 가지고 있다고 가정합시다. 각각의 고객은 다른 많은 주문을 가지고 있다면, 관계를 사용하지 않는 경우 이 모델들의 선언이 다음과 같이 될 것입니다.</p>
<notextile>
<div class="code_container">
<pre class="brush: ruby; gutter: false; toolbar: false">
class Customer < ActiveRecord::Base
end
class Order < ActiveRecord::Base
end
</pre>
</div>
</notextile>
<p>여기서, 이미 존재하는 한 고객의 새로운 주문을 추가하길 원하다고 가정해 봅시다. 우리는 다음과 같이 해야 할 것입니다.</p>
<notextile>
<div class="code_container">
<pre class="brush: ruby; gutter: false; toolbar: false">
@order = Order.create(:order_date => Time.now,
:customer_id => @customer.id)
</pre>
</div>
</notextile>
<p>또는 고객을 삭제하고, 그 고객 관련 모든 주문도 삭제해야 한다면 이런 코드를 보시게 될 겁니다.</p>
<notextile>
<div class="code_container">
<pre class="brush: ruby; gutter: false; toolbar: false">
@orders = Order.where(:customer_id => @customer.id)
@orders.each do |order|
order.destroy
end
@customer.destroy
</pre>
</div>
</notextile>
<p>활성 레코드 관계를 사용한다면, 이 두 <em>고객과 주문</em> 모델 사이에 관계가 있음을 선언해 줌으로써 일괄 처리가 가능해 집니다. 여기 수정된 코드를 보시죠.</p>
<notextile>
<div class="code_container">
<pre class="brush: ruby; gutter: false; toolbar: false">
class Customer < ActiveRecord::Base
has_many :orders, :dependent => :destroy
end
class Order < ActiveRecord::Base
belongs_to :customer
end
</pre>
</div>
</notextile>
<p>이 수정을 통해서 우리는 한 고객의 새로운 주문 생성이 쉬워졌음을 다음과 같이 알수 있습니다. (떨렁 한줄이예요.)</p>
<notextile>
<div class="code_container">
<pre class="brush: ruby; gutter: false; toolbar: false">
@order = @customer.orders.create(:order_date => Time.now)
</pre>
</div>
</notextile>
<p>한 고객과 관련된 모든 주문의 삭제는 더더욱 쉬워 졌어요. 다음을 보세요.</p>
<notextile>
<div class="code_container">
<pre class="brush: ruby; gutter: false; toolbar: false">
@customer.destroy
</pre>
</div>
</notextile>
<p>다양한 관계의 종류를 더 배우시길 원하신다면, 다음 안내서의절(section)을 읽어 주세요. 다음에 소개되는 것들로는 (1) 관계와 관련된 기법들, 묘수들, (2)레일즈에서 제공되는 관계와 연관된 함수들, 그리고 옵션들을 완전하게 설명하는 참고자료가 되겠습니다.</p>
<p>h3(#). 2 관계의 유형들</p>
<p>레일즈에서, <em>관계</em> 는 활성 레코드 모델들간의 연관을 말합니다. 관련은 매크로 스타일의 호출로 구현되어 있어서, 우리가 선언만 하면 모델들 사이에 만들어 집니다. 예를 들면, 한 모델이 다른 모델에 속해있다는 뜻의 <tt>belongs_to</tt> 관계를 선언하면 당신은 주열쇠(primary key)-외부열쇠(foreign key) 정보를 이들 모델들의 예(인스턴스, instance)들 사이에 생성하라는 명령을 레일즈에 하게 되는 것입니다. 게다가 이들 모델에 여러 유용함수들이 추가되어 사용할수 있게 됩니다. 레일즈은 다음 여섯 가지의 관계형을 지원합니다.</p>
<ul>
<li><tt>belongs_to</tt></li>
<li><tt>has_one</tt></li>
<li><tt>has_many</tt></li>
<li><tt>has_many :through</tt></li>
<li><tt>has_one :through</tt></li>
<li><tt>has_and_belongs_to_many</tt></li>
</ul>
<p>각각의 의미로는 <tt>belongs_to</tt> B는 B “객체의 예에 속해있다”, <tt>has_one</tt> B는 B “객체의 예를 하나 갖는다”, <tt>has_many</tt> B는 B “객체의 예를 여러개 갖는다”, <tt>has_many: through</tt> B는 B “객체의 예를 통해서 여러개 갖는다”, <tt>has_one :through</tt> B는 B “객체의 예를를 통해서 하나 갖는다”, 마지막으로 <tt>has_and_belongs_to_many</tt> B는 B “객체의 예에 속해 있으면서 동시에 B 객체의 예를 많이 갖는다” 입니다.</p>
<p>이 이후로, 당신은 여러 형태의 관계를 어떻게 선언하고 사용하는 지를 배우게 될 것입니다. 이에 앞서서 각각의 관련 유형이 사용되는 상황을 간략하게 먼저 설명드리겠습니다.</p>
<h4 id="belongs_to">2.1 <tt>belongs_to</tt> 관련</h4>
<p>하나의 <tt>belongs_to</tt> 관련은 다른 모델과의 1: 1 연관을 정의하는데, 한 모델의 예가 다른 모델의 예에 속하게 됩니다. 예를 들어서, 당신의 응용 프로그램이 앞서 설명한 고객과 주문을 포함한다고 가정하겠습니다. 이때 하나의 주문이 오직 하나의 고객에만 관련되어 있다면 당신은 주문 모델을 다음과 같이 선언하게 될것입니다.</p>
<notextile>
<div class="code_container">
<pre class="brush: ruby; gutter: false; toolbar: false">
class Order < ActiveRecord::Base
belongs_to :customer
end
</pre>
</div>
</notextile>
<p><img src="images/belongs_to.png" title="belongs_to Association Diagram" alt="belongs_to Association Diagram" /></p>
<h4 id="has_one">2.2 <tt>has_one</tt> 관련</h4>
<p><tt>has_one</tt> 관련 또한 다른 모델과의 1:1 관계를 규정합니만 다른 의미와 결과를 갖이게 됩니다. 이 관계는 하나의 모델의 일예가 다른 모델의 일예를 소유하거나 포함하는 것을 의미합니다. 예를 들면당신의 응용프로그램에서 구매부서에서 사용되며 납품회사를 관린한다고 칩시다. 각 납품회사 각각 하나의 계정을 가지고 있다면, 우리는 이납품회사모델을 다음과 같이 선언할 것입니다.</p>
<notextile>
<div class="code_container">
<pre class="brush: ruby; gutter: false; toolbar: false">
class Supplier < ActiveRecord::Base
has_one :account
end
</pre>
</div>
</notextile>
<p><img src="images/has_one.png" title="has_one Association Diagram" alt="has_one Association Diagram" /></p>
<h4 id="has_many">2.3 <tt>has_many</tt> 관련</h4>
<p><tt>has_many</tt> 다른 모델과 1:다(多:많음) 관계를 말합니다. 아마도 당신은 이 관계가 <tt>belong_to</tt>관계의 반대 관점이라는 것을 알게 될 것입니다. 이 관계는 다를 모델의 예를 하나도 가지고 있지 않거나 또는 복수개 가지고 있을 때(즉, 0개에서 여러개를 가지고 있을 때) 에 사용하게 됩니다. 예를 들면, 고객과 주문을 처리하는 당신의 응용 프로그램에서 고객 모델이 다음과 같이 선언될 수 있겠습니다.</p>
<notextile>
<div class="code_container">
<pre class="brush: ruby; gutter: false; toolbar: false">
class Customer < ActiveRecord::Base
has_many :orders
end
</pre>
</div>
</notextile>
<p>주의: <tt>has_many</tt> B 관계를 선언하는 경우에orders 와 같이 B가 복수형의 이름을 갖게되는 것을 주목해 주세요.</p>
<p><img src="images/has_many.png" title="has_many Association Diagram" alt="has_many Association Diagram" /></p>
<h4 id="has_many-through">2.4 <tt>has_many : through</tt> 관계</h4>
<p><tt>has_many : through</tt> 관계는 다른 모델과의 多:多 관계를 설정할 때 종종 사용됩니다. 이 관계는 다른 복수(0포함)개의 모델을 제3의 모델을 <em>통해서</em> 가지게 됨을 말합니다. 예를 들면, 내과 의사께서 환자들을 의료 검진하는 상황을 생각해 봅시다. 일반적으로 의료 검진이 예약을 통해서만 가능하기에, 이에 상응하는 관계를 다음과 같이 정의 될 수 있겠습니다.</p>
<notextile>
<div class="code_container">
<pre class="brush: ruby; gutter: false; toolbar: false">
class Physician < ActiveRecord::Base
has_many :appointments
has_many :patients, :through => :appointments
end
class Appointment < ActiveRecord::Base
belongs_to :physician
belongs_to :patient
end
class Patient < ActiveRecord::Base
has_many :appointments
has_many :physicians, :through => :appointments
end
</pre>
</div>
</notextile>
<p><img src="images/has_many_through.png" title="has_many :through Association Diagram" alt="has_many :through Association Diagram" /></p>
<p>연결모델 집합은 API를 통해서 관리됩니다. 예를 들어 내과 의사 객체 예 physician에는 patients API가 있는데 이것에 다른 집한 patients를 대입할 수 있습니다. 다음을 보시죠.</p>
<notextile>
<div class="code_container">
<pre class="brush: ruby; gutter: false; toolbar: false">
physician.patients = patients
</pre>
</div>
</notextile>
<p>새로운 연결 모델들은 새롭게 연관된 객체 예들로 생성되고, 데이터 베이스의 행이 사라진다면 관련 객체들도 사라질 것입니다.</p>
<p>경고: 연결 모델의 자동 삭제는 직접적이어서 파괴 되부름 함수(destroy callback)의 호출이 없음을 주의해 주세요.</p>
<p><tt>has_many :through</tt> 관계는 중첩된 <tt>has_many</tt> 관계를 간략하게 하는 "지름길"로 유용하게 사용되곤 합니다. 예를 들면 만약 하나의 문서가 여러 절을 가지고 있고, 하나의 절은 많은 문단을 가지고 있을때 만약 한문서의 모든 문단의 단순 집합을 얻길 희망한다면, 다음과 같이 설정이 가능합니다.</p>
<notextile>
<div class="code_container">
<pre class="brush: ruby; gutter: false; toolbar: false">
class Document < ActiveRecord::Base
has_many :sections
has_many :paragraphs, :through => :sections
end
class Section < ActiveRecord::Base
belongs_to :document
has_many :paragraphs
end
class Paragraph < ActiveRecord::Base
belongs_to :section
end
</pre>
</div>
</notextile>
<p>With <tt>:through => :sections</tt> specified, Rails will now understand:</p>
<notextile>
<div class="code_container">
<pre class="brush: ruby; gutter: false; toolbar: false">
@document.paragraphs
</pre>
</div>
</notextile>
<h4 id="has_one-through">2.5 <tt>has_one :through</tt> 관련</h4>
<p><tt>has_one :through</tt> 관련은 또 다른 모델과의 1:1 연관을 설정합니다. 이 관련은 선언 모델이 제삼의 모델을 <em>통해서</em> 다른 모델과 관련을 갖게 됩니다. 예를 들면, 각각의 납품회사가 하나의 계정을 갖고, 각 계정은 계정내역을 가지고 있을떄에, 다음과 같은 모델을 생성하게 됩니다.</p>
<notextile>
<div class="code_container">
<pre class="brush: ruby; gutter: false; toolbar: false">
class Supplier < ActiveRecord::Base
has_one :account
has_one :account_history, :through => :account
end
class Account < ActiveRecord::Base
belongs_to :supplier
has_one :account_history
end
class AccountHistory < ActiveRecord::Base
belongs_to :account
end
</pre>
</div>
</notextile>
<p><img src="images/has_one_through.png" title="has_one :through Association Diagram" alt="has_one :through Association Diagram" /></p>
<h4 id="has_and_belongs_to_many">2.6 <tt>has_and_belongs_to_many</tt> 관련</h4>
<p><tt>has_and_belongs_to_many</tt> 관련은 다른 모델과다多:多 연결을 사이에 그 어떤 모델도 없이 직접 생성한다. 예를 들어, 응용 프로그램이 부품과 이의 조립품을 포함하는데, 조립품은 많은 부품을 가지면, 한 부품은 많은 부품에 사용된다면, 우리는 다음의 모델을 선언하게 된다.</p>
<notextile>
<div class="code_container">
<pre class="brush: ruby; gutter: false; toolbar: false">
class Assembly < ActiveRecord::Base
has_and_belongs_to_many :parts
end
class Part < ActiveRecord::Base
has_and_belongs_to_many :assemblies
end
</pre>
</div>
</notextile>
<p><img src="images/habtm.png" title="has_and_belongs_to_many Association Diagram" alt="has_and_belongs_to_many Association Diagram" /></p>
<h4 id="belongs_to-has_one">2.7 <tt>belongs_to</tt> 와 <tt>has_one</tt> 의 선택</h4>
<p>만약 당신이 두 모델 사이의 1:1 연관을 설정하고자 하고, 한 모델에게는 <tt>belongs_to</tt> 를 다른 모델에는 <tt>has_one</tt> 를 설정해야 할 경우, 어떤 모델을 어떻게 선택해야 할까요?</p>
<p>구별법으로는 어디에 외부열쇠(foreign key)를 (이것은<tt>belongs_to</tt> 관계를 선언하는 객체의 데이터 베이스 테이블에 부착된다) 넣을 것인지에 달려있습니다. 그렇지만 당신은 실재 데이터의 의미 생각해야합니다. <tt>has_one</tt> 관계는 어떤 사물이 당신의 것이라는 것을 말하며 그 사물은 당신에 속해있음을 가리키게 됩니다. 예를 들면, 납품 회사가 계정을 가지고 있는 것이 계정이 납품회사를 가지는 것보다 더 그럴듯 하지 않나요? 다음의 예를 보시죠.</p>
<notextile>
<div class="code_container">
<pre class="brush: ruby; gutter: false; toolbar: false">
class Supplier < ActiveRecord::Base
has_one :account
end
class Account < ActiveRecord::Base
belongs_to :supplier
end
</pre>
</div>
</notextile>
<p>생성된 마이그레이션 코드는 다음과 같이 생기게 됩니다.</p>
<notextile>
<div class="code_container">
<pre class="brush: ruby; gutter: false; toolbar: false">
class CreateSuppliers < ActiveRecord::Migration
def self.up
create_table :suppliers do |t|
t.string :name
t.timestamps
end
create_table :accounts do |t|
t.integer :supplier_id
t.string :account_number
t.timestamps
end
end
def self.down
drop_table :accounts
drop_table :suppliers
end
end
</pre>
</div>
</notextile>
<p>주의: <tt>t.integer :supplier_id</tt> 의 사용은 외부 열쇠의 이름을 명확하게 한다. 현재 레일즈 버전에서는 당신은<tt>t.references :supplier</tt>을 사용하여 구체적인 구현을 추상화 할수 있다.</p>
<h4 id="has_many-through-has_and_belongs_to_many">2.8 <tt>has_many :through</tt> 와 <tt>has_and_belongs_to_many</tt> 의 선택</h4>
<p>레일즈는 모델들간에 두개의 多:多 관계를 선언하는 방법을 지원합니다. 그중 간단한 방법은 <tt>has_and_belongs_to_many</tt> 을 사용하는 것인다, 이 방법은 “직접적”으로 관계를 만들게 됩니다.</p>
<notextile>
<div class="code_container">
<pre class="brush: ruby; gutter: false; toolbar: false">
class Assembly < ActiveRecord::Base
has_and_belongs_to_many :parts
end
class Part < ActiveRecord::Base
has_and_belongs_to_many :assemblies
end
</pre>
</div>
</notextile>
<p>두번째 多:多 관계를 정의하는 방법인 <tt>has_many :through</tt>은 연결모델을 통해서 “간접적”으로 관계를 만듭니다.</p>
<notextile>
<div class="code_container">
<pre class="brush: ruby; gutter: false; toolbar: false">
class Assembly < ActiveRecord::Base
has_many :manifests
has_many :parts, :through => :manifests
end
class Manifest < ActiveRecord::Base
belongs_to :assembly
belongs_to :part
end
class Part < ActiveRecord::Base
has_many :manifests
has_many :assemblies, :through => :manifests
end
</pre>
</div>
</notextile>
<p>가장 기본이 되는 원칙중 하나는, 우리가 연결 모델을 만들때에 이것이 “독립된” 것으로 간주되어야 할 경우에는<tt>has_many :through</tt>를 사용하는 것이 더 좋다는 것입니다. 만약, 우리가 그 어떤 것도 연결 모델 자체가 필요 치 않더면<tt>has_and_belongs_to_many</tt> 관계를 사용하는 게 더 단순한 방법이고 따라서 바람직합니다(하지만 이방법도 데이터베이스의 연결테이블(joining table)이 생성된다는 것 잊지 마세요).</p>
<p>만약 연결 모델상에 검증(validations), 되부름, 추가 속성등이 필요하다면, <tt>has_many :through</tt>를 사용하셔야 합니다.</p>
<h4 id="polymorphic">2.9 폴리모픽(polymorphic: 다중) 관계</h4>
<p>약간은 진일보한 관계로써, <em>폴리모픽 관계</em> 라는 것이 있습니다. 이 폴리모펙 관계를 이용하면, 하나의 모델이 하나 또는 여러 모델에 속할 수 있습니다. 예를 들면, 우리가 사진(picture)이라는 모델을 가지고 있다고 가정해 보겠습니다. 사진이라는 모델이 직원(employee) 모델 또는 생산품(product) 모델에 속할 수 있다면 다음과 같이 정의될 수 있겠습니다.</p>
<notextile>
<div class="code_container">
<pre class="brush: ruby; gutter: false; toolbar: false">
class Picture < ActiveRecord::Base
belongs_to :imageable, :polymorphic => true
end
class Employee < ActiveRecord::Base
has_many :pictures, :as => :imageable
end
class Product < ActiveRecord::Base
has_many :pictures, :as => :imageable
end
</pre>
</div>
</notextile>
<p>당신은 폴리모픽 <tt>belongs_to</tt> 선언을 그 어떤 다른모델도 사용할 수 있는 인터페이스를 설정한 것으로 생각할 수도 있습니다. <tt>Employee</tt>모델의 실예에서 당신은 <tt>@employee.pictures</tt> 처럼 사진집합을 접근하여 읽어들일 수 있습니다.</p>
<p>단순히, <tt>@product.pictures</tt> 라고 불러 사용할 수 있습니다.</p>
<p>만약 <tt>Picture</tt> 모델의 실예를 하나 가지고 있다면, 우리는<tt>@picture.imageable</tt> 호출을 통해서 이것이 속한 부(parent)를 접근할수 있습니다. 이것이 작동하기 위해서는, 우린 이 폴리모픽 인터페이스를 선언하는 외부 열쇠 행과 유형 행 모두를 다음과 같이 선언하여야 합니다.</p>
<notextile>
<div class="code_container">
<pre class="brush: ruby; gutter: false; toolbar: false">
class CreatePictures < ActiveRecord::Migration
def self.up
create_table :pictures do |t|
t.string :name
t.integer :imageable_id
t.string :imageable_type
t.timestamps
end
end
def self.down
drop_table :pictures
end
end
</pre>
</div>
</notextile>
<p>이 마이그레이션은 <tt>t.references</tt> 형식(폼)을 이용해 다음과 같이 더 간략화 될수 있겠습니다.</p>
<notextile>
<div class="code_container">
<pre class="brush: ruby; gutter: false; toolbar: false">
class CreatePictures < ActiveRecord::Migration
def self.up
create_table :pictures do |t|
t.string :name
t.references :imageable, :polymorphic => true
t.timestamps
end
end
def self.down
drop_table :pictures
end
end
</pre>
</div>
</notextile>
<p><img src="images/polymorphic.png" title="Polymorphic Association Diagram" alt="Polymorphic Association Diagram" /></p>
<p>h4(#). 2.10 자체 연결</p>
<p>데이터 모델을 설계할 때에 당신은 한 모델이 그 모델 자신과 연관이 있는 경우를 종종 발견하게 될 것입니다. 예를 들면, 모든 직원들을 하나의 데이터 베이스 모델로 저장하길 원하지만, 직원들 중 관리자(manager)와 팀원(subordinates)의 관계를 추적하고 싶어한다고 가정해 보겠습니다. 이러한 상황은 자체연결 관계로 다음과 같이 모델링 될수 있습니다.</p>
<notextile>
<div class="code_container">
<pre class="brush: ruby; gutter: false; toolbar: false">
class Employee < ActiveRecord::Base
has_many :subordinates, :class_name => "Employee",
:foreign_key => "manager_id"
belongs_to :manager, :class_name => "Employee"
end
</pre>
</div>
</notextile>
<p>이 설정을 사용할 때에 우리는<tt>@employee.subordinates</tt> 와 <tt>@employee.manager</tt> 를 접근하여 사용할 수 있습니다.</p>
<p>h3(#). 3 팁, 묘수, 그리고 경고</p>
<p>여기서 우리가 레일즈 응용프로그램에서 효과적으로 활성 레크도관계를 사용하기 위해 몇가지 알아야 할 것들이 있습니다.</p>
<ul>
<li>케쉬(chach임시저장) 제어하기</li>
<li>이름 충돌 피하기</li>
<li>스키마(schema) 만들기</li>
<li>관련 범위 제어하기</li>
</ul>
<p>h4(#). 3.1 케쉬 제어하기</p>
<p>관계와 관련된 모든 함수는 임시 저장을 하게되는데, 이 말은 가장 최근들어 수행된 데이터베이스 질의를 결과를 기억한다는 것을 말합니다. 이 임시저장은 함수들 사이에서 심지어 공유되기도 합니다. 다음 예를 보시죠.</p>
<notextile>
<div class="code_container">
<pre class="brush: ruby; gutter: false; toolbar: false">
customer.orders # 데이터베이스의 주문들 을 읽음
customer.orders.size # 데이터 베이스의 케쉬 사용
customer.orders.empty? # 데이퍼 베이스의 케쉬 사용
</pre>
</div>
</notextile>
<p>만약 응응 프로그램의 다른 부분에서 관련된 데이터를 수정하여 메모리상의 케쉬를 갱신하고 싶은 경우에는 다음과 같이<tt>true</tt> 를 관계호출시에 인자로 넘겨 주시면 됩니다.</p>
<notextile>
<div class="code_container">
<pre class="brush: ruby; gutter: false; toolbar: false">
customer.orders # 데이터 베이스의 주문들을 읽음
customer.orders.size # 데이터 베이스의 케쉬 사용
customer.orders(true).empty? # 케쉬를 무시하고 데이터 베이스 읽음
</pre>
</div>
</notextile>
<p>h4(#). 3.2 이름 충돌 피하기</p>
당신은 관계를 정의할 때에 아무이름이나 사용할 수 있는 것은 아닙니다. 관계를 생성할 때에 관련된 모델에 관계명과 동일한 함수가 생성되기 때문에<tt>ActiveRecord::Base</tt> 의 함수와 동일한 이름을 관계명으로 사용하는 것은 바람직 하지 않습니다. 이렇게 할 경우, 관계 함수가 활성 레코드 기초함수를 덮어써버리게 되기 때문입니다. 예를 들어, <tt>attributes</tt> 또는 <tt>connection</tt> 은 관계 명으로 바람직 하지 않습니다.
<p>h4(#). 3.3 스키마 갱신하기</p>
<p>관계는 대단히 유용합니다. 그렇지만 이것이 마술일 수는 없습니다. 우리에게는 관계와 데이타 베이스 스키마가 부합 되도록 관리할 책임이 있습니다. 실재로 이 말은 우리가 만들 관계의 종류에 따라서 두가지 의미를 갖습니다. <tt>belongs_to</tt> 관계를 사용한다면, 외래 열쇠를 생성해야 할 것이고, <tt>has_and_belongs_to_many</tt> 에 대해서는 올바른 연결 테이블을 생성해야 합니다.</p>
<h5 id="belongs_to">3.3.1 <tt>belongs_to</tt> 관계를 위한 외래 열쇠 만들기</h5>
<p><tt>belongs_to</tt> 관계를 만들때에, 당신은 올바른 외래키를 만들 필요가 있다. 예를 들어 다음 모델을 생각해 보자.</p>
<notextile>
<div class="code_container">
<pre class="brush: ruby; gutter: false; toolbar: false">
class Order < ActiveRecord::Base
belongs_to :customer
end
</pre>
</div>
</notextile>
<p>이 선언은 올바른 외래 열쇠의 선언을 다른 주문 테이블에 저장해야 한다.</p>
<notextile>
<div class="code_container">
<pre class="brush: ruby; gutter: false; toolbar: false">
class CreateOrders < ActiveRecord::Migration
def self.up
create_table :orders do |t|
t.datetime :order_date
t.string :order_number
t.integer :customer_id
end
end
def self.down
drop_table :orders
end
end
</pre>
</div>
</notextile>
만약 당신이 모델을 만든 한참 후에 관계를 생성했다면, 당신은 필요한 외래 열쇠를 제공하고자 <tt>belongs_to</tt> 마이그레이션을 생성하는 것을 기억해야 한다.
<h5 id="has_and_belongs_to_many">3.3.2 <tt>has_and_belongs_to_many</tt> 관계를 위한 연결테이블 생성하기</h5>
<p>만약 우리가<tt>has_and_belongs_to_many</tt> 관계를 생성한다면, 우리는 연결 테이블을 명확하게 생성할 필요가 있습니다. <tt>:join_table</tt> 옵션을 사용하여연결 테이블의 이름을 명확하게 밝히지 않는 이상에는, 활성 레코드는 클래스명을 알파벳 순으로 배열한 이름을 사용할 것입니다. 따라서 고객(customer)과 주문(order) 모델사이의 연결은 “customers_orders” 명을 연결 테이블의 이름으로 사용하게 될텐데 그 이유는 고객의 영문단어 첫글자 "c"가 주문의 영문단어 첫글자 “o” 보다 알파벳 순으로 먼저이기 때문입니다.</p>
<p>모델명간의 우선순우를 알파벳 순으로 결정할 때에 문자열을 위한 객체<tt>String</tt> 에 정의된 <tt><</tt> 연산자(operator)가 사용됩니다. 이 말은 비교되는 문자열의 길이가 다르때에는 짧은 문자열의 길이까지만을 서로 비교하게 되는데, 이래고 같을 경우에는, 길이가 긴 문자열이 알파벳 순으로 더 뒤에 놓이게 됩니다. 예를 들면두 모델 “paper_boxes” 와 “papers” 를 연결하는 테이블의 생성시를 생각해 보겠습니다. 짧은 문자열의 길이까지만을 비교함으로 내부적으로"paper_” 와 “papers” 를 비교하게 되고, 문자’_’ 보다 ‘s’ 가 더 <em>앞서</em> 므로, 연결 테이블 이름은 “papers_paper_boxes” 로 생성되지 않고, 대신 “papers_paper_boxes” 으로 생성됩니다.</p>
<p>이름이 무엇이던 간에, 우리는 올바른 마이그레이션을 통해 연결 테이블을 손수 생성해야만 합니다. 예를 들면 다음 관계예제들과 같이 말입니다.</p>
<notextile>
<div class="code_container">
<pre class="brush: ruby; gutter: false; toolbar: false">
class Assembly < ActiveRecord::Base
has_and_belongs_to_many :parts
end
class Part < ActiveRecord::Base
has_and_belongs_to_many :assemblies
end
</pre>
</div>
</notextile>
<p>이 모델들은 <tt>assemblies_parts</tt> 테이블의 생성을 위해서 마이그레이션이 필요합니다. 이 테이블은 주열쇠 없이 생성되어야만 합니다.</p>
<notextile>
<div class="code_container">
<pre class="brush: ruby; gutter: false; toolbar: false">
class CreateAssemblyPartJoinTable < ActiveRecord::Migration
def self.up
create_table :assemblies_parts, :id => false do |t|
t.integer :assembly_id
t.integer :part_id
end
end
def self.down
drop_table :assemblies_parts
end
end
</pre>
</div>
</notextile>
<p>우리는<tt>:id => false</tt> 를 <tt>create_table</tt>를 인자로 넘겼습니다. 그 이유는 그 테이블이 모델을 표현하고 있지 않기 때문이며 제대로 작동하기 위해서 관계는 그러한 인자가 필요합니다. 만약 당신이<tt>has_and_belongs_to_many</tt>관계를 사용할 때에 깨진 모델 아이디나 아이디 충돌 예외처리와 같은 이상한 수행결과를 발견한다면, 아마도 이와 같이 인자를 넘기지 않았기 때문일 수 있습니다.</p>
<p>h4(#). 3.4 관계 범위 제어하기</p>
<p>기본으로 관계는 현 모델의 범위내에서 객체의 예들을 찾습니다. 이것은 우리가 활성 레코드 모델을 선언할 때에 중요할 수 있습니다. 다음 예를 보시죠.</p>
<notextile>
<div class="code_container">
<pre class="brush: ruby; gutter: false; toolbar: false">
module MyApplication
module Business
class Supplier < ActiveRecord::Base
has_one :account
end
class Account < ActiveRecord::Base
belongs_to :supplier
end
end
end
</pre>
</div>
</notextile>
<p>이 예제 코드는 문제 없이 작동 할 것입니다. 왜냐하면<tt>Supplier</tt> 와 <tt>Account</tt> 객체가 동일한 범위, 즉, 모듈내에서 정의가 됐기 때문입니다. 반대로, 다음의 예에서는 <tt>Supplier</tt> 와 <tt>Account</tt> 제대로 작동하지 않을텐데 그 이유는 이들이 다른 범위에서 정의됐기 때문이죠.</p>
<notextile>
<div class="code_container">
<pre class="brush: ruby; gutter: false; toolbar: false">
module MyApplication
module Business
class Supplier < ActiveRecord::Base
has_one :account
end
end
module Billing
class Account < ActiveRecord::Base
belongs_to :supplier
end
end
end
</pre>
</div>
</notextile>
<p>다른 이름공간(namespace)에 정의된 모델들 사이를 관계 맺고자 할 경우, 우리는 완전한 객체 명을 관계정의에 명시해야 됩니다. 다음을 보시죠.</p>
<notextile>
<div class="code_container">
<pre class="brush: ruby; gutter: false; toolbar: false">
module MyApplication
module Business
class Supplier < ActiveRecord::Base
has_one :account,
:class_name => "MyApplication::Billing::Account"
end
end
module Billing
class Account < ActiveRecord::Base
belongs_to :supplier,
:class_name => "MyApplication::Business::Supplier"
end
end
end
</pre>
</div>
</notextile>
<p>h3(#). 4 자세한 관계 참고자료</p>
<p>The following sections give the details of each type of association, including the methods that they add and the options that you can use when declaring an association.
다음 절은 각 관계의 유형별 상세자료를 담고 있습는데, 생성되는 객체 함수들과 이들의 옵션들을 보시게 될 것입니다.</p>
<h4 id="belongs_to">4.1 <tt>belongs_to</tt> 관계 참고자료</h4>
<p><tt>belongs_to</tt> 관계는 다른 모델과의 1:1 관계를 생성한다. 데이터베이스 용어로는 이 관계객체가 외래 열쇠를 갖게된다고 말합니다. 만약 관련된 다른 객체가 외래 열쇠를 가지게 된다면, 우리는<tt>has_one</tt> 관계를 대신 사용해야 합니다.</p>
<h5 id="belongs_to">4.1.1 <tt>belongs_to</tt> 에 의해서 추가되는 함수들</h5>
<p><tt>belongs_to</tt> 관계를 선언할 때에, 선언하는 클래스는 자동으로 다음의 네가지 함수들을 가지게 됩니다.</p>
<ul>
<li><tt><em>association</em>(force_reload = false)</tt></li>
<li><tt><em>association</em>=(associate)</tt></li>
<li><tt>build_<em>association</em>(attributes = {})</tt></li>
<li><tt>create_<em>association</em>(attributes = {})</tt></li>
</ul>
<p>이 모든 함수들에서<tt><em>association</em></tt>는<tt>belongs_to</tt> 관계에 정의된 모델명으로 바뀌어야 합니다. 다음의 예를 보시죠.</p>
<notextile>
<div class="code_container">
<pre class="brush: ruby; gutter: false; toolbar: false">
class Order < ActiveRecord::Base
belongs_to :customer
end
</pre>
</div>
</notextile>
<p>각 모델의 실예는 이러한 함수들을 갖게 됩니다. 즉, 주문(order)의 실예(instance)는 관련된 다음의 함수를 가지게 됩니다.</p>
<notextile>
<div class="code_container">
<pre class="brush: ruby; gutter: false; toolbar: false">
customer
customer=
build_customer
create_customer
</pre>
</div>
</notextile>
<h6 id="belongs_to-association">4.1.1.1 <tt><em>association</em>(force_reload = false)</tt></h6>
<tt><em>association</em></tt> 메서드는 관련된 객체를 반환하는데, 만약, 관련된 객체가 존재하지 않으면 <tt>nil</tt> 을 반환합니다.
<notextile>
<div class="code_container">
<pre class="brush: ruby; gutter: false; toolbar: false">
@customer = @order.customer
</pre>
</div>
</notextile>
<p>만약 데이터베이스로부터 관련객체을 벌써 읽었다면 이 것은 임시저장소(케쉬)의 것이 반환될 것입니다. 캐쉬의 것을 사용하는 이 방법을 무시하고 데이터 베이스의 것을 읽기를 원한다면, <tt>force_reload</tt> 에 해당하는 인자값을 <tt>true</tt> 로 넘기셔야 합니다.</p>
<h6 id="belongs_to-association_equal">4.1.1.2 <tt><em>association</em>=(associate)</tt></h6>
<tt><em>association</em>=</tt> 메서드는 관련된 객체를 설정할 것입니다. 내부적으로 이것은 관련 객체의 (데이터 베이스의) 주 열쇠값을 꺼내와 (데이터베이스의) 외부 열쇠로 복사하는 것과 같습니다.
<notextile>
<div class="code_container">
<pre class="brush: ruby; gutter: false; toolbar: false">
@order.customer = @customer
</pre>
</div>
</notextile>
<h6 id="belongs_to-build_association">4.1.1.3 <tt>build_<em>association</em>(attributes = {})</tt></h6>
<p>The <tt>build_<em>association</em></tt> method returns a new object of the associated type. This object will be instantiated from the passed attributes, and the link through this object’s foreign key will be set, but the associated object will <em>not</em> yet be saved.</p>
<notextile>
<div class="code_container">
<pre class="brush: ruby; gutter: false; toolbar: false">
@customer = @order.build_customer(:customer_number => 123,
:customer_name => "John Doe")
</pre>
</div>
</notextile>
<h6 id="belongs_to-create_association">4.1.1.4 <tt>create_<em>association</em>(attributes = {})</tt></h6>
<p>The <tt>create_<em>association</em></tt> method returns a new object of the associated type. This object will be instantiated from the passed attributes, and the link through this object’s foreign key will be set. In addition, the associated object <em>will</em> be saved (assuming that it passes any validations).</p>
<notextile>
<div class="code_container">
<pre class="brush: ruby; gutter: false; toolbar: false">
@customer = @order.create_customer(:customer_number => 123,
:customer_name => "John Doe")
</pre>
</div>
</notextile>
<h5 id="options-for-belongs_to">4.1.2 Options for <tt>belongs_to</tt></h5>
<p>In many situations, you can use the default behavior of <tt>belongs_to</tt> without any customization. But despite Rails’ emphasis of convention over customization, you can alter that behavior in a number of ways. This section covers the options that you can pass when you create a <tt>belongs_to</tt> association. For example, an association with several options might look like this:</p>
<notextile>
<div class="code_container">
<pre class="brush: ruby; gutter: false; toolbar: false">
class Order < ActiveRecord::Base
belongs_to :customer, :counter_cache => true,
:conditions => "active = 1"
end
</pre>
</div>
</notextile>
<p>The <tt>belongs_to</tt> association supports these options:</p>
<ul>
<li><tt>:autosave</tt></li>
<li><tt>:class_name</tt></li>
<li><tt>:conditions</tt></li>
<li><tt>:counter_cache</tt></li>
<li><tt>:dependent</tt></li>
<li><tt>:foreign_key</tt></li>
<li><tt>:include</tt></li>
<li><tt>:polymorphic</tt></li>
<li><tt>:readonly</tt></li>
<li><tt>:select</tt></li>
<li><tt>:touch</tt></li>
<li><tt>:validate</tt></li>
</ul>
<h6 id="belongs_to-autosave">4.1.2.1 <tt>:autosave</tt></h6>
<p>If you set the <tt>:autosave</tt> option to <tt>true</tt>, Rails will save any loaded members and destroy members that are marked for destruction whenever you save the parent object.</p>
<h6 id="belongs_to-class_name">4.1.2.2 <tt>:class_name</tt></h6>
<p>If the name of the other model cannot be derived from the association name, you can use the <tt>:class_name</tt> option to supply the model name. For example, if an order belongs to a customer, but the actual name of the model containing customers is <tt>Patron</tt>, you’d set things up this way:</p>
<notextile>
<div class="code_container">
<pre class="brush: ruby; gutter: false; toolbar: false">
class Order < ActiveRecord::Base
belongs_to :customer, :class_name => "Patron"
end
</pre>
</div>
</notextile>
<h6 id="belongs_to-conditions">4.1.2.3 <tt>:conditions</tt></h6>
<p>The <tt>:conditions</tt> option lets you specify the conditions that the associated object must meet (in the syntax used by an <span class="caps">SQL</span> <tt>WHERE</tt> clause).</p>
<notextile>
<div class="code_container">
<pre class="brush: ruby; gutter: false; toolbar: false">
class Order < ActiveRecord::Base
belongs_to :customer, :conditions => "active = 1"
end
</pre>
</div>
</notextile>
<h6 id="belongs_to-counter_cache">4.1.2.4 <tt>:counter_cache</tt></h6>
<p>The <tt>:counter_cache</tt> option can be used to make finding the number of belonging objects more efficient. Consider these models:</p>
<notextile>
<div class="code_container">
<pre class="brush: ruby; gutter: false; toolbar: false">
class Order < ActiveRecord::Base
belongs_to :customer
end
class Customer < ActiveRecord::Base
has_many :orders
end
</pre>
</div>
</notextile>
<p>With these declarations, asking for the value of <tt>@customer.orders.size</tt> requires making a call to the database to perform a <tt>COUNT(*)</tt> query. To avoid this call, you can add a counter cache to the <em>belonging</em> model:</p>
<notextile>
<div class="code_container">
<pre class="brush: ruby; gutter: false; toolbar: false">
class Order < ActiveRecord::Base
belongs_to :customer, :counter_cache => true
end
class Customer < ActiveRecord::Base
has_many :orders
end
</pre>
</div>
</notextile>
<p>With this declaration, Rails will keep the cache value up to date, and then return that value in response to the <tt>size</tt> method.</p>
<p>Although the <tt>:counter_cache</tt> option is specified on the model that includes the <tt>belongs_to</tt> declaration, the actual column must be added to the <em>associated</em> model. In the case above, you would need to add a column named <tt>orders_count</tt> to the <tt>Customer</tt> model. You can override the default column name if you need to:</p>
<notextile>
<div class="code_container">
<pre class="brush: ruby; gutter: false; toolbar: false">
class Order < ActiveRecord::Base
belongs_to :customer, :counter_cache => :count_of_orders
end
class Customer < ActiveRecord::Base
has_many :orders
end
</pre>
</div>
</notextile>
<p>Counter cache columns are added to the containing model’s list of read-only attributes through <tt>attr_readonly</tt>.</p>
<h6 id="belongs_to-dependent">4.1.2.5 <tt>:dependent</tt></h6>
<p>If you set the <tt>:dependent</tt> option to <tt>:destroy</tt>, then deleting this object will call the <tt>destroy</tt> method on the associated object to delete that object. If you set the <tt>:dependent</tt> option to <tt>:delete</tt>, then deleting this object will delete the associated object <em>without</em> calling its <tt>destroy</tt> method.</p>
<div class='warning'><p>You should not specify this option on a <tt>belongs_to</tt> association that is connected with a <tt>has_many</tt> association on the other class. Doing so can lead to orphaned records in your database.</p></div>
<h6 id="belongs_to-foreign_key">4.1.2.6 <tt>:foreign_key</tt></h6>
<p>By convention, Rails guesses that the column used to hold the foreign key on this model is the name of the association with the suffix <tt>_id</tt> added. The <tt>:foreign_key</tt> option lets you set the name of the foreign key directly:</p>
<notextile>
<div class="code_container">
<pre class="brush: ruby; gutter: false; toolbar: false">
class Order < ActiveRecord::Base
belongs_to :customer, :class_name => "Patron",
:foreign_key => "patron_id"
end
</pre>
</div>
</notextile>
<div class='info'><p>In any case, Rails will not create foreign key columns for you. You need to explicitly define them as part of your migrations.</p></div>
<h6 id="belongs_to-includes">4.1.2.7 <tt>:include</tt></h6>
<p>You can use the <tt>:include</tt> option to specify second-order associations that should be eager-loaded when this association is used. For example, consider these models:</p>
<notextile>
<div class="code_container">
<pre class="brush: ruby; gutter: false; toolbar: false">
class LineItem < ActiveRecord::Base
belongs_to :order
end
class Order < ActiveRecord::Base
belongs_to :customer
has_many :line_items
end
class Customer < ActiveRecord::Base
has_many :orders
end
</pre>
</div>
</notextile>
<p>If you frequently retrieve customers directly from line items (<tt>@line_item.order.customer</tt>), then you can make your code somewhat more efficient by including customers in the association from line items to orders:</p>
<notextile>
<div class="code_container">
<pre class="brush: ruby; gutter: false; toolbar: false">
class LineItem < ActiveRecord::Base
belongs_to :order, :include => :customer
end
class Order < ActiveRecord::Base
belongs_to :customer
has_many :line_items
end
class Customer < ActiveRecord::Base
has_many :orders
end
</pre>
</div>
</notextile>
<div class='note'><p>There’s no need to use <tt>:include</tt> for immediate associations – that is, if you have <tt>Order belongs_to :customer</tt>, then the customer is eager-loaded automatically when it’s needed.</p></div>
<h6 id="belongs_to-polymorphic">4.1.2.8 <tt>:polymorphic</tt></h6>
<p>Passing <tt>true</tt> to the <tt>:polymorphic</tt> option indicates that this is a polymorphic association. Polymorphic associations were discussed in detail <a href="#polymorphic-associations">earlier in this guide</a>.</p>
<h6 id="belongs_to-readonly">4.1.2.9 <tt>:readonly</tt></h6>
<p>If you set the <tt>:readonly</tt> option to <tt>true</tt>, then the associated object will be read-only when retrieved via the association.</p>
<h6 id="belongs_to-select">4.1.2.10 <tt>:select</tt></h6>
<p>The <tt>:select</tt> option lets you override the <span class="caps">SQL</span> <tt>SELECT</tt> clause that is used to retrieve data about the associated object. By default, Rails retrieves all columns.</p>
<div class='info'><p>If you set the <tt>:select</tt> option on a <tt>belongs_to</tt> association, you should also set the <tt>foreign_key</tt> option to guarantee the correct results.</p></div>
<h6 id="belongs_to-touch">4.1.2.11 <tt>:touch</tt></h6>
<p>If you set the <tt>:touch</tt> option to <tt>:true</tt>, then the <tt>updated_at</tt> or <tt>updated_on</tt> timestamp on the associated object will be set to the current time whenever this object is saved or destroyed:</p>
<notextile>
<div class="code_container">
<pre class="brush: ruby; gutter: false; toolbar: false">
class Order < ActiveRecord::Base
belongs_to :customer, :touch => true
end
class Customer < ActiveRecord::Base
has_many :orders
end
</pre>
</div>
</notextile>
<p>In this case, saving or destroying an order will update the timestamp on the associated customer. You can also specify a particular timestamp attribute to update:</p>
<notextile>
<div class="code_container">
<pre class="brush: ruby; gutter: false; toolbar: false">
class Order < ActiveRecord::Base
belongs_to :customer, :touch => :orders_updated_at
end
</pre>
</div>
</notextile>
<h6 id="belongs_to-validate">4.1.2.12 <tt>:validate</tt></h6>
<p>If you set the <tt>:validate</tt> option to <tt>true</tt>, then associated objects will be validated whenever you save this object. By default, this is <tt>false</tt>: associated objects will not be validated when this object is saved.</p>
<h5 id="belongs_to-how_to_know_whether_theres_an_associated_object">4.1.3 How To Know Whether There’s an Associated Object?</h5>
<p>To know whether there’s and associated object just check <tt><em>association</em>.nil?</tt>:</p>
<notextile>
<div class="code_container">
<pre class="brush: ruby; gutter: false; toolbar: false">
if @order.customer.nil?
@msg = "No customer found for this order"
end
</pre>
</div>
</notextile>
<h5 id="belongs_to-when_are_objects_saved">4.1.4 When are Objects Saved?</h5>
<p>Assigning an object to a <tt>belongs_to</tt> association does <em>not</em> automatically save the object. It does not save the associated object either.</p>
<h4 id="has_one-association-reference">4.2 <tt>has_one</tt> Association Reference</h4>
<p>The <tt>has_one</tt> association creates a one-to-one match with another model. In database terms, this association says that the other class contains the foreign key. If this class contains the foreign key, then you should use <tt>belongs_to</tt> instead.</p>
<h5 id="methods-added-by-has_one">4.2.1 Methods Added by <tt>has_one</tt></h5>
<p>When you declare a <tt>has_one</tt> association, the declaring class automatically gains four methods related to the association:</p>
<ul>
<li><tt><em>association</em>(force_reload = false)</tt></li>
<li><tt><em>association</em>=(associate)</tt></li>
<li><tt>build_<em>association</em>(attributes = {})</tt></li>
<li><tt>create_<em>association</em>(attributes = {})</tt></li>
</ul>
<p>In all of these methods, <tt><em>association</em></tt> is replaced with the symbol passed as the first argument to <tt>has_one</tt>. For example, given the declaration:</p>
<notextile>
<div class="code_container">
<pre class="brush: ruby; gutter: false; toolbar: false">
class Supplier < ActiveRecord::Base
has_one :account
end
</pre>
</div>
</notextile>
<p>Each instance of the <tt>Supplier</tt> model will have these methods:</p>
<notextile>
<div class="code_container">
<pre class="brush: ruby; gutter: false; toolbar: false">
account
account=
build_account
create_account
</pre>
</div>
</notextile>
<div class='note'><p>When initializing a new <tt>has_one</tt> or <tt>belongs_to</tt> association you must use the <tt>build_</tt> prefix to build the association, rather than the <tt>association.build</tt> method that would be used for <tt>has_many</tt> or <tt>has_and_belongs_to_many</tt> associations. To create one, use the <tt>create_</tt> prefix.</p></div>
<h6 id="has_one-association">4.2.1.1 <tt><em>association</em>(force_reload = false)</tt></h6>