Truy vấn dữ liệu với ActiveRecord - Truy vấn với quan hệ has_many

Giới thiệu

Bạn đã khá quen thuộc với các quan hệ giữa các Model trong ActiveRecord, đặc biệt các quan hệ như belong_to, has_one hay has_many. Như vậy đến nay, bạn đã có thể sử dụng các quan hệ này để lấy ra các tập đối tượng như các bài viết trước đây trong loạt bài này. Có rất nhiều điều có ích khác mà Rails cho phép bạn làm với các quan hệ này. Phần tóm tắt này sẽ làm nổi bật một số trong những phương pháp hữu ích ActiveRecord cung cấp cho bạn.

Những điểm cần chú ý

Hãy xem xét các câu hỏi sau và sau đó sử dụng chúng để kiểm tra những điều bạn thu nhận được sau khi đọc bài viết này:

  • Làm thế nào để Rails biết được bảng và khoá ngoại nào được sử dụng khi bạn có một quan hệ (ví dụ User.first.posts)?
  • Khi nào bạn cần chỉ định tuỳ chọn :class_name cho một quan hệ
  • :foreign_key là gì?
  • :source là gì?
  • Thế nào là polymorphic và khi nào bạn nên sử dụng nó?
  • Hai cách sử dụng liên kết để tạo ra một đối tượng mới thay vì chỉ gọi YourObject.new? Tại sao điều này hữu ích? Những phương pháp được ưa thích?
  • Làm thế nào để hệ thống tự xoá tất cả bài viết của một người dùng nếu người dùng đó bị xóa?
  • Làm thế nào để tạo ra 1 quan hệ tự join, giống như How do you set up a self-association, like with Users following Users?

Kiến thức cơ bản

Foreign KeysClass Names

Khi bạn tạo ra một quan hệ, Rails làm ra hai giả định chính - đầu tiên, rằng các lớp của quan hệ chỉ dựa trực tiếp vào tên của quan hệ, và, thứ hai, khoá ngoại trong bất kỳ quan hệ belongs_tosẽ được gọi là yourassociationname_id. Bất cứ khi nào bạn thay đổi khỏi những giá trị mặc định, bạn chỉ cần cho Rails biết những thay đổi này.

Một ví dụ khá đơn giản như: Một User có thể tạo ra nhiều bài Post cho 1 blog:

# app/models/user.rb
    class User < ActiveRecord::Base
      has_many :posts
    end

    # app/models/post.rb
    class Post < ActiveRecord::Base
      belongs_to :user
    end

Vì vậy, bạn có thể lấy danh sách tất cả các bài Post của User đầu tiên với User.first.posts hoặc tác giả của bài viết đầu tiên với Post.first.user. Rails tự tìm một khóa ngoại trong bảng Post là user_id. Nếu bạn chạy lệnh Post.first.user, Rails sẽ tìm trong bảng Users tương ứng với ID của cột user_id trong bảng Posts

Nhưng nếu bạn muốn có 2 loại User có thể đăng bài Post như "author" và "editor"? Trong trường hợp này bạn sẽ cần 2 khóa ngoại khác nhau trong bảng Posts, , chẳng hạn một khóa sẽ là author_id và khóa còn lại là editor_id. Làm sao bạn chỉ cho Rails rằng mỗi khóa đó thực sự chỏ tới 1 User nào đó (để nó biết tìm trong bảng User cho chúng)? Chỉ cần chỉ ra các lớp trong quan hệ của bạn chỏ tới bằng cách sử dụng tùy chọn class_name:

# app/models/post.rb
    class Post < ActiveRecord::Base
      belongs_to :author, :class_name => "User"
      belongs_to :editor, :class_name => "User"
    end

All Rights Reserved