Tags:
Forums: 

"แก้ปัญหาได้แล้ว ดูคอมเมนด้านล่าง"

ใช้อยู่ 3 table ดังนี้

users(id,username,password)
comments(id,body,user_id)
profiles(id,...,user_id)

model มีความสัมพันธ์ดังนี้

class User < ActiveRecord::Base
has_many :comments
has_one :profile

end

class Comment < ActiveRecord::Base
belongs_to :users

end

class Profile < ActiveRecord::Base
belongs_to :user

end

ตัว comments ที่มีความสัมพันธ์ แบบ has_many ใช้ได้ดีไม่มีปัญหา
พอจะใช้ profile แบบ has_one ผมก็เข้าใจว่าแค่เปลี่ยนการเรียกจาก plural เป็น singular แค่นั้น
แต่ profile ที่มีความสัญพันธ์แบบ one-to-one กลับมีปัญหา
เช่น ใน controller นี้


@user = User.find(7)
@profile = Profile.new(params[:newprofile])
@user.profile << @profile

พอรัน Rails แจ้ง error ว่า

You have a nil object when you didn't expect it!
You might have expected an instance of Array.
The error occurred while evaluating nil.<<

งงครับ? มันผิดพลาดที่ตรงไหน

พอเข้าไปอ่าน Doc ของ ActiveRecord

ก็ยังสับสัน เท่าที่ผมอ่านเข้าใจคือ แทนที่จะ user 1 คน จะมี 1 profile

แต่ใน doc อธิบายเป็นว่า 1 profile จะมี user 1 คน ...ผมไม่เข้าใจครับ

ทำไมมันตรงกันข้ามกลับความเป็นจริง ทำไมไม่เหมือน has_many?

อยากให้พี่ๆช่วยอธิบายทีครับ
ขอบคุณมากครับ

Get latest news from Blognone
By: GiggsWalk
AndroidUbuntu
on 17 January 2009 - 09:37 #81246

Yippy! แก้ปัญหาได้แล้วครับ
คือ แทนที่เราจะใส่ profile โดยสั่ง @user.profile << @profile เหมือน has_many
ใน has_one เราต้องสั่งเป็น @user.profile = @profile แทน
เปลี่ยน '<<' เป็น '='

By: Sikachu
ContributoriPhoneIn Love
on 17 January 2009 - 20:35 #81334
Sikachu's picture

มาขยายความ เพือ่ให้เข้าใจเพิ่ม :)

เนื่องจากว่า ถ้าคุณเรียก attributes ที่เป็น has_many
สิ่งที่มัน return กลับมา จะเป็น array ของ objects ครับ

เช่น

@user.comments # =>  [#<Comment:0x35a5188>,#<Comment:0x35a2474>]
@user.comments.class # => Array

แต่ถ้าเป็น attribute ที่เป็น has_one สิ่งที่ return มาจะเป็น object หรือ nil ครับ (ถ้าไม่ได้ associate กับอะไรเลย)

@user.profile # => #<Profile:0x485ab32>
@user.profile.class # => Profile

เพราะฉะนั้น เหตุผลที่คุณสามารถใช้ << ได้ ก็เพราะว่าจริงๆ แล้วมันไปเรียก Array.<< นั่นเองครับ หรือว่าหมายถึงการเพิ่ม object เข้าใน array นั่นเองครับ

ส่วนของ has_one ที่คุณต้องใช้ = เพราะว่ามันเป็นการกำหนดค่าๆ เดียวครับ เหมือนการกำหนดค่าตัวแปรทั่วๆ ไปนั่นแลครับ :D

บล็อกของผม: http://sikachu.com


บล็อกของผม: http://sikachu.com

By: GiggsWalk
AndroidUbuntu
on 17 January 2009 - 21:55 #81354 Reply to:81334

ขอบคุณมากครับ คุณ Sikachu
ที่แท้มันก็เรื่องปกติๆนี่เอง ที่งงคงเพราะ เจ้า << นี่แหล่ะครับ ที่เข้าใจผิดไปว่าใช้เชื่อมความสัมพันธ์
เลยพยายามยัดความสัมพันธ์ด้วย << อยู่อย่างนั้น เสียเวลาตั้งนานกับเรื่องนี้ ไม่ไหวเลย 555 ^^'