edge
เพิ่มเติมที่ rubyonrails.org: เพิ่มเติมเกี่ยวกับ Ruby on Rails

พื้นฐานของ Active Record

เอกสารนี้เป็นการแนะนำเกี่ยวกับ Active Record

หลังจากอ่านเอกสารนี้คุณจะรู้:

1 Active Record คืออะไร?

Active Record เป็นส่วนของ MVC - โมเดล - ซึ่งเป็นชั้นของระบบที่รับผิดชอบในการแสดงข้อมูลและตรรกะทางธุรกิจ Active Record ช่วยให้สามารถสร้างและใช้งานอ็อบเจ็กต์ทางธุรกิจที่ต้องการเก็บข้อมูลไว้ในฐานข้อมูลได้ง่ายขึ้น นี่เป็นการนำเสนอของรูปแบบ Active Record ซึ่งเป็นรายละเอียดของระบบ Object Relational Mapping

1.1 รูปแบบ Active Record

Active Record ถูกอธิบายโดย Martin Fowler ในหนังสือของเขา Patterns of Enterprise Application Architecture ใน Active Record อ็อบเจ็กต์จะมีข้อมูลที่ต้องการเก็บไว้และพฤติกรรมที่ใช้กับข้อมูลนั้น Active Record เชื่อว่าการสร้างตรรกะการเข้าถึงข้อมูลเป็นส่วนหนึ่งของอ็อบเจ็กต์จะช่วยให้ผู้ใช้ของอ็อบเจ็กต์นั้นรู้วิธีการเขียนและอ่านข้อมูลจากฐานข้อมูล

1.2 Object Relational Mapping

Object Relational Mapping หรือที่เรียกว่า ORM ในทางทั่วไป เป็นเทคนิคที่เชื่อมต่ออ็อบเจ็กต์ที่มีคุณสมบัติและความสัมพันธ์ในแอปพลิเคชันกับตารางในระบบจัดการฐานข้อมูลที่เกี่ยวข้อง โดยใช้ ORM คุณสมบัติและความสัมพันธ์ของอ็อบเจ็กต์ในแอปพลิเคชันสามารถเก็บและเรียกคืนข้อมูลจากฐานข้อมูลได้ง่ายๆ โดยไม่ต้องเขียนคำสั่ง SQL โดยตรงและมีการเข้าถึงฐานข้อมูลทั้งหมดน้อยลง

หมายเหตุ: ความรู้พื้นฐานเกี่ยวกับระบบจัดการฐานข้อมูลที่เกี่ยวข้อง (RDBMS) และ structured query language (SQL) จะช่วยให้เข้าใจ Active Record ได้อย่างเต็มที่ กรุณาอ้างอิง บทเรียนนี้ (หรือ บทเรียนนี้) หรือศึกษาจากแหล่งอื่นๆ หากคุณต้องการเรียนรู้เพิ่มเติม

1.3 Active Record เป็นเฟรมเวิร์ค ORM

Active Record ให้เราสิ่งที่สำคัญหลายอย่าง โดยสิ่งที่สำคัญที่สุดคือความสามารถในการ:

  • แสดงตัวแบบและข้อมูลของตัวแบบ
  • แสดงความสัมพันธ์ระหว่างตัวแบบเหล่านี้
  • แสดงลำดับชั้นที่สืบทอดผ่านตัวแบบที่เกี่ยวข้อง
  • ตรวจสอบตัวแบบก่อนที่จะเก็บไว้ในฐานข้อมูล
  • ดำเนินการฐานข้อมูลในรูปแบบเชิงวัตถุ

2 การปฏิบัติตามกฎเกณฑ์ของ Active Record

เมื่อเขียนแอปพลิเคชันโดยใช้ภาษาหรือเฟรมเวิร์คอื่นๆ อาจจำเป็นต้องเขียนโค้ดการกำหนดค่ามากมาย สำหรับเฟรมเวิร์ค ORM โดยทั่วไป อย่างไรก็ตาม หากคุณปฏิบัติตามกฎเกณฑ์ที่ Rails นำมาใช้ คุณจะต้องเขียนการกำหนดค่าน้อยมาก (บางกรณีไม่ต้องกำหนดค่าเลย) เมื่อสร้าง Active Record models ความคิดคือหากคุณกำหนดค่าแอปพลิเคชันของคุณในวิธีเดียวกันเป็นปกติเสมอ นี่คือวิธีที่เป็นค่าเริ่มต้น ดังนั้น การกำหนดค่าชัดเจนจะต้องใช้เฉพาะในกรณีที่คุณไม่สามารถปฏิบัติตามกฎเกณฑ์มาตรฐานได้

2.1 กฎเกณฑ์การตั้งชื่อ

โดยค่าเริ่มต้น Active Record ใช้กฎเกณฑ์บางส่วนในการหาวิธีการสร้างการจับคู่ระหว่างตัวแบบและตารางฐานข้อมูล Rails จะทำการพหล่งชื่อคลาสของคุณเพื่อหาตารางฐานข้อมูลที่เกี่ยวข้อง ดังนั้นสำหรับคลาส Book คุณควรมีตารางฐานข้อมูลที่ชื่อว่า books กลไกการพหล่งของ Rails เป็นกลไกที่มีประสิทธิภาพมาก สามารถพหล่ง (และเปลี่ยนรูป) คำทั่วไปและคำที่ไม่เป็นไปตามกฎได้ ในกรณีที่ใช้ชื่อคลาสที่ประกอบด้วยคำสองคำหรือมากกว่า ชื่อคลาสต้องเป็นตามแนวคิดของ Ruby โดยใช้รูปแบบ CamelCase ในขณะที่ชื่อตารางต้องใช้รูปแบบ snake_case ตัวอย่าง: * คลาสโมเดล - เป็นรูปเดียวกับคำแรกของแต่ละคำที่เริ่มต้นด้วยตัวพิมพ์ใหญ่ (เช่น BookClub). * ตารางฐานข้อมูล - เป็นรูปพหูพจน์โดยใช้ขีดล่างคั่นคำ (เช่น book_clubs).

โมเดล / คลาส ตาราง / สกีม่า
Article articles
LineItem line_items
Deer deers
Mouse mice
Person people

2.2 กฎเกณฑ์สกีม่า

Active Record ใช้กฎเกณฑ์ในการตั้งชื่อคอลัมน์ในตารางฐานข้อมูล ขึ้นอยู่กับวัตถุประสงค์ของคอลัมน์เหล่านี้

  • คีย์ต่างประเทศ - ฟิลด์เหล่านี้ควรมีชื่อตามรูปแบบ singularized_table_name_id (เช่น item_id, order_id) นี่คือ ฟิลด์ที่ Active Record จะค้นหาเมื่อคุณสร้างความสัมพันธ์ระหว่าง โมเดลของคุณ
  • คีย์หลัก - โดยค่าเริ่มต้น Active Record จะใช้คอลัมน์จำนวนเต็มที่ชื่อว่า id เป็นคีย์หลักของตาราง (bigint สำหรับ PostgreSQL และ MySQL, integer สำหรับ SQLite) เมื่อใช้ Active Record Migrations เพื่อสร้างตารางของคุณ คอลัมน์นี้จะถูกสร้างโดยอัตโนมัติ

นอกจากนี้ยังมีชื่อคอลัมน์ทางเลือกบางอย่างที่จะเพิ่มคุณสมบัติเพิ่มเติมให้กับอินสแตนซ์ของ Active Record:

  • created_at - จะถูกตั้งค่าโดยอัตโนมัติเป็นวันที่และเวลาปัจจุบันเมื่อบันทึกครั้งแรก
  • updated_at - จะถูกตั้งค่าโดยอัตโนมัติเป็นวันที่และเวลาปัจจุบันเมื่อมีการสร้างหรืออัปเดตบันทึก
  • lock_version - เพิ่ม การล็อกแบบมุมมองเชิงโต้ตอบ ให้กับโมเดล
  • type - ระบุว่าโมเดลใช้ การสืบทอดแบบตารางเดียว
  • (association_name)_type - เก็บประเภทสำหรับ การสัมพันธ์หลายรูปแบบ
  • (table_name)_count - ใช้ในการแคชจำนวนวัตถุที่เกี่ยวข้องในการสัมพันธ์ เช่น คอลัมน์ comments_count ในคลาส Article ที่มีหลายอินสแตนซ์ของ Comment จะแคชจำนวนความคิดเห็นที่มีอยู่สำหรับแต่ละบทความ

หมายเหตุ: แม้ว่าชื่อคอลัมน์เหล่านี้จะเป็นทางเลือก แต่จริงๆ แล้ว Active Record จองไว้แล้ว อย่าใช้คำสงวนเว้นแต่คุณต้องการฟังก์ชันพิเศษเพิ่มเติม เช่น type เป็นคำสงวนที่ใช้ในการระบุตารางที่ใช้การสืบทอดแบบตารางเดียว (STI) หากคุณไม่ได้ใช้ STI ลองใช้คำสงวนที่คล้ายกันเช่น "context" ซึ่งอาจยังอธิบายข้อมูลที่คุณกำลังจัดรูปแบบได้อย่างถูกต้อง

3 การสร้างโมเดล Active Record

เมื่อสร้างแอปพลิเคชัน คลาส ApplicationRecord จะถูกสร้างขึ้นใน app/models/application_record.rb นี่คือคลาสหลักสำหรับโมเดลทั้งหมดในแอปพลิเคชัน และมันเป็นสิ่งที่ทำให้คลาสรูบีเป็นโมเดล Active Record

ในการสร้างโมเดล Active Record ให้สืบทอดคลาส ApplicationRecord และคุณก็พร้อมที่จะเริ่มต้น:

class Product < ApplicationRecord
end

นี้จะสร้างโมเดล Product ที่มีการแมปกับตาราง products ในฐานข้อมูล โดยการทำเช่นนี้คุณยังสามารถแมปคอลัมน์ของแต่ละแถวในตารางนั้นกับแอตทริบิวต์ของอินสแตนซ์ของโมเดลของคุณได้ สมมติว่าตาราง products ถูกสร้างขึ้นโดยใช้คำสั่ง SQL (หรือหนึ่งในส่วนขยายของ SQL) เช่น:

CREATE TABLE products (
  id int(11) NOT NULL auto_increment,
  name varchar(255),
  PRIMARY KEY  (id)
);

สกีม่าข้างต้นประกาศตารางที่มีคอลัมน์สองคอลัมน์: id และ name แต่ละแถวของตารางนี้แทนสินค้าบางอย่างด้วยพารามิเตอร์สองอย่างเหล่านี้ ดังนั้นคุณจะสามารถเขียนโค้ดเช่นต่อไปนี้: ruby p = Product.new p.name = "Some Book" puts p.name # "Some Book"

4 การแทนที่การตั้งชื่อ

ถ้าคุณต้องการที่จะปฏิบัติตามการตั้งชื่อที่แตกต่างหรือต้องการใช้แอปพลิเคชัน Rails ของคุณกับฐานข้อมูลที่เก่า ไม่มีปัญหาคุณสามารถแทนที่การตั้งค่าเริ่มต้นได้อย่างง่ายดาย

เนื่องจาก ApplicationRecord สืบทอดมาจาก ActiveRecord::Base โมเดลของแอปพลิเคชันของคุณจะมีเมธอดที่มีประโยชน์มากมายที่ใช้ได้ ตัวอย่างเช่น คุณสามารถใช้เมธอด ActiveRecord::Base.table_name= เพื่อกำหนดชื่อตารางที่ควรใช้:

class Product < ApplicationRecord
  self.table_name = "my_products"
end

หากคุณทำเช่นนั้น คุณจะต้องกำหนดชื่อคลาสที่เป็นเจ้าภาพของ fixtures (my_products.yml) ด้วยเมธอด set_fixture_class ในการกำหนดค่าการทดสอบ:

# test/models/product_test.rb
class ProductTest < ActiveSupport::TestCase
  set_fixture_class my_products: Product
  fixtures :my_products
  # ...
end

คุณยังสามารถแทนที่คอลัมน์ที่ควรใช้เป็น primary key ของตารางได้โดยใช้เมธอด ActiveRecord::Base.primary_key=:

class Product < ApplicationRecord
  self.primary_key = "product_id"
end

หมายเหตุ: Active Record ไม่รองรับการใช้คอลัมน์ที่ไม่ใช่ primary key ที่ชื่อ id.

หมายเหตุ: หากคุณพยายามสร้างคอลัมน์ที่ชื่อ id ที่ไม่ใช่ primary key Rails จะโยนข้อผิดพลาดในระหว่างการโยกย้าย เช่น you can't redefine the primary key column 'id' on 'my_products'. To define a custom primary key, pass { id: false } to create_table.

5 CRUD: การอ่านและเขียนข้อมูล

CRUD เป็นตัวย่อสำหรับสี่คำกริยาที่เราใช้ในการดำเนินการกับข้อมูล: Create, Read, Update และ Delete Active Record สร้างเมธอดขึ้นโดยอัตโนมัติเพื่อให้แอปพลิเคชันสามารถอ่านและจัดการข้อมูลที่เก็บอยู่ในตารางได้

5.1 Create

ออบเจ็กต์ Active Record สามารถสร้างขึ้นจากแฮช, บล็อก หรือตั้งค่าแอตทริบิวต์ของมันเองหลังจากการสร้าง การเรียกใช้เมธอด new จะสร้างออบเจ็กต์ใหม่ขึ้น ในขณะที่ create จะสร้างออบเจ็กต์และบันทึกลงในฐานข้อมูล

ตัวอย่างเช่น กำหนดให้มีโมเดล User ที่มีแอตทริบิวต์ชื่อ name และ occupation เรียกใช้เมธอด create จะสร้างและบันทึกบันทึกใหม่ลงในฐานข้อมูล:

user = User.create(name: "David", occupation: "Code Artist")

โดยใช้เมธอด new ออบเจ็กต์สามารถสร้างขึ้นได้โดยไม่ต้องบันทึก:

user = User.new
user.name = "David"
user.occupation = "Code Artist"

การเรียกใช้ user.save จะบันทึกบันทึกลงในฐานข้อมูล

สุดท้าย หากมีบล็อกที่ให้ ทั้ง create และ new จะส่งคืนออบเจ็กต์ใหม่ให้กับบล็อกเพื่อทำการเริ่มต้น ในขณะที่เฉพาะ create เท่านั้นที่จะบันทึกออบเจ็กต์ที่ได้จากนั้นลงในฐานข้อมูล:

user = User.new do |u|
  u.name = "David"
  u.occupation = "Code Artist"
end

5.2 Read

Active Record ให้ API ที่มีความหลากหลายสำหรับการเข้าถึงข้อมูลภายในฐานข้อมูล ด้านล่างคือตัวอย่างของเมธอดการเข้าถึงข้อมูลที่ต่างกันที่ Active Record ให้

# ส่งคืนคอลเลกชันที่มีผู้ใช้ทั้งหมด
users = User.all
# ส่งคืนผู้ใช้คนแรก
user = User.first
# ส่งคืนผู้ใช้คนแรกที่ชื่อ David
david = User.find_by(name: 'David')
# ค้นหาผู้ใช้ทั้งหมดที่ชื่อ David ที่เป็น Code Artist และเรียงลำดับตาม created_at จากมากไปน้อย
users = User.where(name: 'David', occupation: 'Code Artist').order(created_at: :desc)

คุณสามารถเรียนรู้เพิ่มเติมเกี่ยวกับการคิวรีของโมเดล Active Record ในเอกสาร Active Record Query Interface

5.3 การอัปเดต

เมื่อได้รับออบเจ็กต์ Active Record แล้ว คุณสามารถแก้ไขแอตทริบิวต์และบันทึกลงในฐานข้อมูลได้

user = User.find_by(name: 'David')
user.name = 'Dave'
user.save

วิธีที่สั้นกว่าคือใช้แฮชแมปแอตทริบิวต์กับค่าที่ต้องการ เช่น

user = User.find_by(name: 'David')
user.update(name: 'Dave')

วิธีนี้เป็นประโยชน์มากที่สุดเมื่อต้องการอัปเดตหลายแอตทริบิวต์ในครั้งเดียว

หากคุณต้องการอัปเดตบันทึกหลายรายการพร้อมกัน โดยไม่ใช้ callbacks หรือ validations คุณสามารถอัปเดตฐานข้อมูลโดยตรงโดยใช้ update_all:

User.update_all max_login_attempts: 3, must_change_password: true

5.4 การลบ

เช่นเดียวกับการเรียกคืน ออบเจ็กต์ Active Record ที่ได้รับ สามารถทำลายได้ซึ่งจะลบออกจากฐานข้อมูล

user = User.find_by(name: 'David')
user.destroy

หากคุณต้องการลบบันทึกหลายรายการพร้อมกัน คุณสามารถใช้เมธอด destroy_by หรือ destroy_all:

# ค้นหาและลบผู้ใช้ทั้งหมดที่ชื่อ David
User.destroy_by(name: 'David')

# ลบผู้ใช้ทั้งหมด
User.destroy_all

6 การตรวจสอบความถูกต้อง

Active Record ช่วยให้คุณสามารถตรวจสอบสถานะของโมเดลก่อนที่จะเขียนลงในฐานข้อมูลได้ มีเมธอดหลายรูปแบบที่คุณสามารถใช้เพื่อตรวจสอบโมเดลของคุณและตรวจสอบว่าค่าแอตทริบิวต์ไม่ว่างเปล่า ไม่ซ้ำกับฐานข้อมูลอยู่แล้ว ตามรูปแบบที่กำหนด และอื่น ๆ

เมื่อใช้เมธอด save create และ update จะทำการตรวจสอบโมเดลก่อนที่จะบันทึกลงในฐานข้อมูล หากโมเดลไม่ถูกต้อง เมธอดเหล่านี้จะคืนค่า false และไม่มีการดำเนินการใด ๆ กับฐานข้อมูล ทั้งหมดเหล่านี้มีเมธอดแบบแบงค์ (เช่น save! create! และ update!) ซึ่งเข้มงวดกว่าโดยเรียกใช้ข้อยกเว้น ActiveRecord::RecordInvalid เมื่อการตรวจสอบล้มเหลว ตัวอย่างอย่างรวดเร็วเพื่อแสดง:

class User < ApplicationRecord
  validates :name, presence: true
end
irb> user = User.new
irb> user.save
=> false
irb> user.save!
ActiveRecord::RecordInvalid: Validation failed: Name can’t be blank

คุณสามารถเรียนรู้เพิ่มเติมเกี่ยวกับการตรวจสอบความถูกต้องในเอกสาร Active Record Validations guide.

7 Callbacks

Callback ใน Active Record ช่วยให้คุณสามารถเชื่อมโยงโค้ดกับเหตุการณ์บางอย่างในไลฟ์เซิลของโมเดลของคุณ สิ่งนี้ช่วยให้คุณเพิ่มพฤติกรรมให้กับโมเดลของคุณโดยการทำงานโดย透明เมื่อเหตุการณ์เหล่านั้นเกิดขึ้น เช่นเมื่อคุณสร้างบันทึกใหม่ อัปเดต ทำลาย และอื่น ๆ

class User < ApplicationRecord
  after_create :log_new_user

  private
    def log_new_user
      puts "A new user was registered"
    end
end
irb> @user = User.create
A new user was registered

คุณสามารถเรียนรู้เพิ่มเติมเกี่ยวกับ Callback ในเอกสาร Active Record Callbacks guide.

8 การเปลี่ยนแปลงโครงสร้างของฐานข้อมูล

Rails มีวิธีที่สะดวกในการจัดการการเปลี่ยนแปลงโครงสร้างของฐานข้อมูลผ่านการเรียกใช้งาน การเปลี่ยนแปลงถูกเขียนในภาษาที่เฉพาะเจาะจงและเก็บไว้ในไฟล์ที่ดำเนินการกับฐานข้อมูลที่ Active Record รองรับ

นี่คือการเปลี่ยนแปลงที่สร้างตารางใหม่ที่ชื่อ publications:

class CreatePublications < ActiveRecord::Migration[7.1]
  def change
    create_table :publications do |t|
      t.string :title
      t.text :description
      t.references :publication_type
      t.references :publisher, polymorphic: true
      t.boolean :single_issue

      t.timestamps
    end
  end
end

โปรดทราบว่าโค้ดด้านบนเป็นระบบที่ไม่ขึ้นกับฐานข้อมูล: มันจะทำงานใน MySQL PostgreSQL SQLite และอื่น ๆ Rails จะเก็บบันทึกว่ามีการทำการอัปเดตใดๆ ที่ถูกบันทึกลงในฐานข้อมูลและจัดเก็บไว้ในตารางที่อยู่ในฐานข้อมูลเดียวกันที่ชื่อว่า schema_migrations

ในการรันการอัปเดตและสร้างตาราง คุณสามารถรันคำสั่ง bin/rails db:migrate และในการย้อนกลับและลบตาราง คุณสามารถรันคำสั่ง bin/rails db:rollback

คุณสามารถเรียนรู้เพิ่มเติมเกี่ยวกับการอัปเดตในเอกสาร Active Record Migrations guide

9 การเชื่อมโยง

การเชื่อมโยงใน Active Record ช่วยให้คุณสามารถกำหนดความสัมพันธ์ระหว่างโมเดลได้ การเชื่อมโยงสามารถใช้เพื่ออธิบายความสัมพันธ์หนึ่งต่อหนึ่ง หนึ่งต่อหลาย และหลายต่อหลาย ตัวอย่างเช่น ความสัมพันธ์ "ผู้เขียนมีหนังสือหลายเล่ม" สามารถกำหนดได้ดังนี้:

class Author < ApplicationRecord
  has_many :books
end

คลาส Author ตอนนี้มีเมธอดที่ใช้ในการเพิ่มและลบหนังสือของผู้เขียน และอื่นๆ อีกมากมาย

คุณสามารถเรียนรู้เพิ่มเติมเกี่ยวกับการเชื่อมโยงในเอกสาร Active Record Associations guide

ข้อเสนอแนะ

คุณสามารถช่วยปรับปรุงคุณภาพของคู่มือนี้ได้

กรุณาช่วยเพิ่มเติมหากพบข้อผิดพลาดหรือข้อผิดพลาดทางความจริง เพื่อเริ่มต้นคุณสามารถอ่านส่วน การสนับสนุนเอกสาร ของเราได้

คุณอาจพบเนื้อหาที่ไม่สมบูรณ์หรือเนื้อหาที่ไม่ได้อัปเดต กรุณาเพิ่มเอกสารที่ขาดหายไปสำหรับเนื้อหาหลัก โปรดตรวจสอบ Edge Guides ก่อนเพื่อตรวจสอบ ว่าปัญหาได้รับการแก้ไขหรือไม่ในสาขาหลัก ตรวจสอบ คู่มือแนวทาง Ruby on Rails เพื่อดูรูปแบบและกฎเกณฑ์

หากคุณพบข้อผิดพลาดแต่ไม่สามารถแก้ไขได้เอง กรุณา เปิดปัญหา.

และสุดท้าย การสนทนาใด ๆ เกี่ยวกับ Ruby on Rails เอกสารยินดีต้อนรับที่สุดใน เว็บบอร์ดอย่างเป็นทางการของ Ruby on Rails.