0Pricing
Ruby Academy · Lekcja

Powiązania

has_many i belongs_to

Powiązania to bezpłatna lekcja Ruby Academy na CoddyKit. To lekcja 3 z 4. Możesz przeczytać całą lekcję poniżej za darmo — a potem ćwiczyć ją interaktywnie w przeglądarce z wbudowanym edytorem kodu i tutorem AI dostępnym 24/7. To część ścieżki edukacyjnej Ruby Academy, a Twój postęp synchronizuje się między webem a aplikacją CoddyKit. Kurs Ruby Academy zawiera 4 lekcji w sumie.

Czym są powiązania?

Powiązania deklarują relacje między modelami, dzięki czemu Active Record może samodzielnie nawigować między powiązanymi wierszami. Zamiast pisać SQL z klauzulą join, można wywoływać metody takie jak user.posts.

  • Odzwierciedlają klucze obce w bazie danych.
  • Automatycznie generują pomocnicze metody.
  • Sprawiają, że kod odzwierciedla domenę.

belongs_to

belongs_to oznacza, że ten model przechowuje klucz obcy wskazujący na inny model. Obiekt Comment, który należy do obiektu Post, ma kolumnę post_id.

class Comment < ApplicationRecord
  belongs_to :post
end

# comment.post returns the parent Post
# Requires a post_id column on comments

has_many

has_many opisuje drugą stronę relacji: jeden rekord ma wiele rekordów innego typu. Obiekt Post ma wiele rekordów Comment. Klucz obcy znajduje się po stronie „wiele”.

class Post < ApplicationRecord
  has_many :comments
end

# post.comments returns all related comments
# post.comments.create(body: "Nice!")

Gdzie znajduje się klucz obcy

Model, który używa belongs_to, przechowuje klucz obcy. W przypadku modeli Post i Comment tabela comments zawiera post_id. Należy skonfigurować to w migracji za pomocą t.references :post lub add_reference.

create_table :comments do |t|
  t.references :post, foreign_key: true
  t.text :body
  t.timestamps
end

Generowane metody

has_many :comments udostępnia kolekcję z przydatnymi metodami:

  • post.comments służy do odczytu.
  • post.comments.create(...) służy do dodawania powiązanego rekordu.
  • post.comments.count służy do zliczania rekordów.
  • post.comment_ids zwraca identyfikatory.
post = Post.find(1)
post.comments.create(body: "First!")
puts post.comments.count

has_one

has_one odwzorowuje relację jeden do jednego, na przykład relację, w której obiekt User ma jeden obiekt Profile. Klucz obcy nadal znajduje się w drugim modelu (profiles.user_id).

class User < ApplicationRecord
  has_one :profile
end

class Profile < ApplicationRecord
  belongs_to :user
end

Relacja wiele do wielu z through

W przypadku relacji wiele do wielu należy użyć modelu pośredniczącego i has_many through. Obiekt Student ma wiele rekordów Course poprzez rekordy Enrollment.

class Student < ApplicationRecord
  has_many :enrollments
  has_many :courses, through: :enrollments
end

class Enrollment < ApplicationRecord
  belongs_to :student
  belongs_to :course
end

Opcje dependent

Za pomocą dependent można określić, co stanie się z rekordami podrzędnymi po usunięciu rekordu nadrzędnego:

  • dependent: :destroy usuwa również rekordy podrzędne.
  • dependent: :nullify czyści ich klucz obcy.
  • dependent: :restrict_with_error blokuje usunięcie.
class Post < ApplicationRecord
  has_many :comments, dependent: :destroy
end

Problem zapytań N+1

Iterowanie po rekordach i odwoływanie się do powiązania może uruchomić jedno zapytanie dla każdego rekordu — budzi to grozę problem N+1. Załadowanie 10 postów wraz z komentarzami może skutkować 11 zapytaniami zamiast 2.

Wraz ze wzrostem ilości danych spowalnia to aplikacje w sposób, który łatwo przeoczyć.

# N+1: one query per post for comments
Post.all.each do |post|
  puts post.comments.count
end

Rozwiązywanie problemu N+1 za pomocą includes

includes nakazuje Active Record wstępnie załadować powiązanie za pomocą kilku zapytań zamiast wielu. Jest to standardowy sposób rozwiązania problemu N+1.

Post.includes(:comments).each do |post|
  puts post.comments.count
end

Własne nazwy za pomocą class_name

Gdy nazwa powiązania nie odpowiada nazwie modelu, należy użyć opcji takich jak class_name i foreign_key. Przykładem jest powiązanie author oparte na modelu User.

class Post < ApplicationRecord
  belongs_to :author, class_name: "User"
end

Szybki test

Sprawdź swoją wiedzę na temat powiązań.

Podsumowanie: powiązania

Poznano sposób łączenia modeli:

  • belongs_to przechowuje klucz obcy, a has_many i has_one opisują drugą stronę relacji.
  • has_many through odwzorowuje relacje wiele do wielu.
  • dependent steruje kaskadowym usuwaniem.
  • Problemu zapytań N+1 należy unikać za pomocą includes.

W następnym kroku integralność danych zostanie zapewniona za pomocą walidacji, a także zostanie omówione wykonywanie zapytań.

Często zadawane pytania

Czy lekcja „Powiązania” jest bezpłatna?

Tak — pełny tekst „Powiązania” jest dostępny za darmo tutaj w sieci. Aby ćwiczyć ją interaktywnie (wbudowany edytor kodu i tutor AI dostępny 24/7) i odblokować resztę kursu Ruby Academy, przejdź na CoddyKit PRO. Kurs Ruby Academy zawiera 4 lekcji w sumie.

Co nauczysz się w „Powiązania”?

has_many i belongs_to Ćwiczysz Ruby Academy z praktycznym kodem, który uruchamiasz bezpośrednio w przeglądarce, a tutor AI dostępny 24/7 odpowiada na Twoje pytania podczas pracy nad lekcją.

Czy potrzebuję doświadczenia, aby zacząć Ruby Academy?

Nie wymagamy żadnego doświadczenia. Ruby Academy w CoddyKit jest strukturyzowany dla początkujących i zaawansowanych użytkowników, więc możesz zacząć tutaj lub od początku i uczyć się w swoim tempie. To lekcja 3 z 4.

Ile czasu zajmuje lekcja „Powiązania”?

Większość lekcji CoddyKit trwa około 5–10 minut. Każda lekcja to mały, interaktywny krok, dzięki czemu robisz systematyczne postępy i zawsze wracasz dokładnie do tego samego miejsca — na webie i w aplikacji.

Czy mogę pisać i uruchamiać kod w tej lekcji Ruby Academy?

Tak. Każda lekcja Ruby Academy zawiera wbudowany edytor kodu, więc piszesz i uruchamiasz prawdziwy kod bezpośrednio w przeglądarce i od razu otrzymujesz sprzężenie zwrotne od AI — bez konfiguracji na komputerze.

Wszystkie lekcje w tym kursie

  1. Podstawy Active Record
  2. Migracje
  3. Powiązania
  4. Walidacje i zapytania
← Powrót do Ruby Academy