สร้างแบบจำลองโดยใช้ผู้ใช้: การอ้างอิงกับ user_id: จำนวนเต็ม


177

ฉันสับสนในการสร้างแบบจำลองที่เป็นของโมเดลอื่น หนังสือของฉันใช้ไวยากรณ์นี้เพื่อเชื่อมโยง Micropost กับผู้ใช้:

rails generate model Micropost user_id:integer

แต่http://guides.rubyonrails.org/บอกว่าทำแบบนี้:

rails generate model Micropost user:references

การย้ายข้อมูลที่สร้างโดย 2 เหล่านี้แตกต่างกัน นอกจากนี้สำหรับอดีตวิธีการที่ไม่รางรู้ว่าuser_idเป็นอ้างอิงที่สำคัญต่างประเทศuser? ขอบคุณ!

คำตอบ:


190

ทั้งสองจะสร้างคอลัมน์เดียวกันเมื่อคุณเรียกใช้การย้ายข้อมูล ในคอนโซลทางรถไฟคุณจะเห็นได้ว่านี่เป็นกรณี:

:001 > Micropost
=> Micropost(id: integer, user_id: integer, created_at: datetime, updated_at: datetime)

คำสั่งที่สองเพิ่มbelongs_to :userความสัมพันธ์ในโมเดล Micropost ของคุณในขณะที่คำสั่งแรกไม่ได้ เมื่อมีการระบุความสัมพันธ์นี้ ActiveRecord จะถือว่ารหัสต่างประเทศถูกเก็บไว้ในuser_idคอลัมน์และจะใช้แบบจำลองที่มีชื่อUserเพื่อสร้างอินสแตนซ์ของผู้ใช้ที่เฉพาะเจาะจง

คำสั่งที่สองยังเพิ่มดัชนีในuser_idคอลัมน์ใหม่


1
เป็นไปได้หรือไม่ที่จะสร้างแบบจำลองที่มีการอ้างอิงสองตาราง
praveenkumar

โปรดทราบว่าจะไม่เพิ่มการเชื่อมโยง has_many ในรุ่นอื่น (ผู้ใช้) ซึ่งคุณอาจต้องการเพิ่มเช่นกัน
Sv1

45

วิธีการที่ไม่รางรู้ว่าuser_idเป็นอ้างอิงที่สำคัญต่างประเทศuser?

Rails ตัวเองไม่ได้รู้ว่าเป็นอ้างอิงต่างประเทศที่สำคัญuser_id userในคำสั่งแรกrails generate model Micropost user_id:integerนั้นจะเพิ่มเฉพาะคอลัมน์user_idแต่รางไม่ทราบการใช้คอลัมน์ คุณต้องวางสายในMicropostโมเดลด้วยตนเอง

class Micropost < ActiveRecord::Base
  belongs_to :user
end

class User < ActiveRecord::Base
  has_many :microposts
end

คำหลักbelongs_toและhas_manyกำหนดความสัมพันธ์ระหว่างโมเดลเหล่านี้และประกาศuser_idเป็นคีย์ต่างประเทศต่อUserโมเดล

คำสั่งในภายหลังrails generate model Micropost user:referencesเพิ่มบรรทัดbelongs_to :userในMicropostรูปแบบและขอประกาศว่าเป็นกุญแจต่างประเทศ

FYI การ
ประกาศคีย์ต่างประเทศโดยใช้วิธีการแบบเดิมช่วยให้ Rails ทราบเกี่ยวกับความสัมพันธ์ที่โมเดล / ตารางมี ฐานข้อมูลไม่ทราบเกี่ยวกับความสัมพันธ์ ดังนั้นเมื่อคุณสร้างไดอะแกรม EER โดยใช้ซอฟต์แวร์เช่นMySql Workbenchคุณพบว่าไม่มีเธรดที่สัมพันธ์กันระหว่างโมเดล ชอบในรูปต่อไปนี้ ป้อนคำอธิบายรูปภาพที่นี่

อย่างไรก็ตามหากคุณใช้วิธีการในภายหลังคุณจะพบว่าไฟล์การโยกย้ายของคุณมีลักษณะดังนี้:

def change
    create_table :microposts do |t|
      t.references :user, index: true

      t.timestamps null: false
    end
    add_foreign_key :microposts, :users

ตอนนี้คีย์ foreign ถูกตั้งค่าที่ระดับฐานข้อมูล และคุณสามารถสร้างEERไดอะแกรม ที่เหมาะสมป้อนคำอธิบายรูปภาพที่นี่


1
มันดูเหมือนว่า Rails ล่าสุดกำเนิดแทนที่add_foreign_keyการกระทำที่มีตัวเลือกforeign_key: trueให้กับสายซึ่งหมายถึงt.references ดังนั้นก็คือตอนนี้index: true t.references :user, foreign_key: trueขณะนี้ไม่มีเอกสารสำหรับforeign_keyตัวเลือกที่ใช้ได้ดังนั้นนี่เป็นเพียงข้อสันนิษฐานของฉัน
Franklin Yu

โอ้add_referenceกระทำมี:foreign_keyตัวเลือกที่เพิ่มที่เหมาะสมข้อ จำกัด ที่สำคัญต่างประเทศ ฉันเดาว่าตัวเลือกนี้จะทำแบบเดียวกันเมื่อสร้างตาราง
Franklin Yu

คุณจะส่งออก ruby ​​db ไปยัง workbench ได้อย่างไร? คุณสามารถตอบคำถามนี้ได้ที่นี่: stackoverflow.com/questions/42982921/…
Krawalla

การadd_foreign_key :microposts, :users สร้าง Rails แตกต่างกันหรือไม่?
ไลนัส

17

สำหรับการประชุมที่ผ่านมาการกำหนดค่า Rails เริ่มต้นเมื่อคุณอ้างอิงตารางอื่นด้วย

 belongs_to :something

something_idคือการมองหา

referencesหรือbelongs_toเป็นวิธีการใหม่ในการเขียนอดีตที่มีนิสัยใจคอน้อย

ข้อสำคัญคืออย่าลืมว่ามันจะไม่สร้างกุญแจต่างประเทศให้คุณ ในการทำเช่นนั้นคุณต้องตั้งค่าอย่างชัดเจนโดยใช้:

t.references :something, foreign_key: true
t.belongs_to :something_else, foreign_key: true

หรือ (สังเกตพหูพจน์):

add_foreign_key :table_name, :somethings
add_foreign_key :table_name, :something_elses`

1
คุณสามารถอธิบายสิ่งที่คุณหมายถึงโดยบอกว่าการอ้างอิงจะไม่สร้างกุญแจต่างประเทศสำหรับคุณ มันแตกต่างจากคำสั่งแรกโดยใช้ user_id: จำนวนเต็มโดยตรงได้อย่างไร
Shailesh

มันไม่ใช่ยกเว้นในกรณีที่คุณใช้:polymorphicตัวเลือก (ซึ่ง IMHO สำหรับกรณีส่วนใหญ่ไม่ใช่ความคิดที่ดี) หากคุณต้องการที่จะใช้ปุ่มต่างประเทศใน ActiveRecord ใช้ชาวต่างชาติ
Krule

1
@Krule Now add_foreign_keyได้ทำให้เป็น ActiveRecord
Franklin Yu
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.