Skip to content

Commit f9628f5

Browse files
committed
Updates person.md
Auto commit by GitBook Editor
1 parent be5cd2c commit f9628f5

File tree

1 file changed

+63
-0
lines changed

1 file changed

+63
-0
lines changed

person.md

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
# 如何讓 Person model 可以指定另一個 person 為 parent
2+
3+
```ruby
4+
irb(main):001:0> john = Person.create(name: "John")
5+
irb(main):002:0> jim = Person.create(name: "Jim", parent: john)
6+
irb(main):003:0> bob = Person.create(name: "Bob", parent: john)
7+
irb(main):004:0> john.children.map(&:name)
8+
=> ["Jim", "Bob"]
9+
```
10+
如何達成這樣的關連呢?首先我們要知道 association 的 target class 是可以另外指定的,而外鍵的欄位也是可以自己定義
11+
12+
```ruby
13+
rails g migration add_parent_id_to_person
14+
# 先增加一個整數欄位 parent_id 到 person table
15+
16+
class Person < ActiveRecord::Base
17+
belongs_to :parent, class: Person
18+
has_many :children, class: Person, foreign_key: :parent_id
19+
end
20+
```
21+
22+
這個問題還可以延伸下去,如果我想達成這樣的效果,需要怎麼實作呢?
23+
```ruby
24+
irb(main):001:0> sally = Person.create(name: "Sally")
25+
irb(main):002:0> sue = Person.create(name: "Sue", parent: sally)
26+
irb(main):003:0> kate = Person.create(name: "Kate", parent: sally)
27+
irb(main):004:0> lisa = Person.create(name: "Lisa", parent: sue)
28+
irb(main):005:0> robin = Person.create(name: "Robin", parent: kate)
29+
irb(main):006:0> donna = Person.create(name: "Donna", parent: kate)
30+
irb(main):007:0> sally.grandchildren.map(&:name)
31+
=> ["Lisa", "Robin", "Donna"]
32+
```
33+
34+
這邊考的是 has_many ... :through => 這個概念
35+
36+
```ruby
37+
class Person < ActiveRecord::Base
38+
belongs_to :parent, class: Person
39+
has_many :children, class: Person, foreign_key: :parent_id
40+
has_many :grandchildren, class: Person, through: :children, source: :children
41+
end
42+
```
43+
44+
這個範例解釋得很好
45+
```ruby
46+
Say you have these models:
47+
48+
Car
49+
Engine
50+
Piston
51+
52+
A car has_one :engine
53+
An engine belongs_to :car
54+
An engine has_many :pistons
55+
Piston belongs_to :engine
56+
57+
A car has_many :pistons, through: :engine
58+
Piston has_one :car, through: :engine
59+
60+
Essentially you are delegating a model relationship to another
61+
model, so instead of having to call car.engine.pistons, you can
62+
just do car.pistons
63+
```

0 commit comments

Comments
 (0)