Sobes.tech
Middle+

Jak zaimplementować dziedziczenie modeli lub polimorficzne asocjacje w Ruby on Rails?

sobes.tech AI

Odpowiedź od AI

W Ruby on Rails dziedziczenie modeli realizuje się za pomocą Single Table Inheritance (STI) lub za pomocą polimorficznych asocjacji.

Single Table Inheritance (STI)

STI jest odpowiednie, gdy różne typy obiektów mają podobne atrybuty, ale różne zachowania. Wszystkie dane są przechowywane w jednej tabeli, a typ obiektu jest określany przez kolumnę type.

  1. Tworzenie tabeli i kolumny type:

    # migracja
    create_table :animals do |t|
      t.string :name
      t.string :type
      t.timestamps
    end
    
  2. Tworzenie klas modeli dziedziczących z klasy bazowej:

    # app/models/animal.rb
    class Animal < ApplicationRecord
      # Logika wspólna dla wszystkich zwierząt
    end
    
    # app/models/dog.rb
    class Dog < Animal
      # Logika specyficzna dla psów
      def bark
        "Woof!"
      end
    end
    
    # app/models/cat.rb
    class Cat < Animal
      # Logika specyficzna dla kotów
      def meow
        "Meow!"
      end
    end
    
  3. Użycie:

    # konsola
    dog = Dog.create(name: "Buddy")
    cat = Cat.create(name: "Whiskers")
    
    animal = Animal.find(dog.id) # Zwróci obiekt Dog
    

Polimorficzne asocjacje

Polimorficzne asocjacje są używane, gdy model może należeć do różnych innych modeli.

  1. Dodanie kolumn _id i _type do modelu powiązanego: Na przykład, jeśli Comment może należeć do Article lub Photo:

    # migracja
    create_table :comments do |t|
      t.text :body
      t.references :commentable, polymorphic: true, null: false
      t.timestamps
    end
    
  2. Deklaracja asocjacji w modelach: W modelu Comment:

    # app/models/comment.rb
    class Comment < ApplicationRecord
      belongs_to :commentable, polymorphic: true
    end
    

    W modelach Article i Photo:

    # app/models/article.rb
    class Article < ApplicationRecord
      has_many :comments, as: :commentable
    end
    
    # app/models/photo.rb
    class Photo < ApplicationRecord
      has_many :comments, as: :commentable
    end
    
  3. Użycie:

    # konsola
    article = Article.create(title: "Porady Rails")
    photo = Photo.create(caption: "Piękny zachód słońca")
    
    article.comments.create(body: "Świetny artykuł!")
    photo.comments.create(body: "Piękne zdjęcie!")
    
    Comment.first.commentable # Zwróci Article
    Comment.last.commentable  # Zwróci Photo
    

Wybór między STI a polimorficznymi asocjacjami zależy od struktury danych i relacji między modelami. STI dla relacji "jest-a" (Dog jest Animal), polimorficzne asocjacje dla relacji "ma-a" (Article ma Comment, Photo ma Comment, gdzie Comment może należeć do Article LUB Photo).