Sobes.tech
Middle+

Cum se implementează moștenirea modelelor sau asocierile polimorfe în Ruby on Rails?

sobes.tech AI

Răspuns de la AI

În Ruby on Rails, moștenirea modelelor se implementează prin Single Table Inheritance (STI) sau prin asocieri polimorfe.

Single Table Inheritance (STI)

STI este potrivit atunci când diferite tipuri de obiecte au atribute similare, dar comportamente diferite. Toate datele sunt stocate într-un singur tabel, iar tipul obiectului este determinat de coloana type.

  1. Crearea tabelului și a coloanei type:

    # migrare
    create_table :animals do |t|
      t.string :name
      t.string :type
      t.timestamps
    end
    
  2. Crearea claselor de modele care moștenesc de la o clasă de bază:

    # app/models/animal.rb
    class Animal < ApplicationRecord
      # Logică comună pentru toate animalele
    end
    
    # app/models/dog.rb
    class Dog < Animal
      # Logică specifică pentru câini
      def bark
        "Woof!"
      end
    end
    
    # app/models/cat.rb
    class Cat < Animal
      # Logică specifică pentru pisici
      def meow
        "Meow!"
      end
    end
    
  3. Utilizare:

    # consolă
    dog = Dog.create(name: "Buddy")
    cat = Cat.create(name: "Whiskers")
    
    animal = Animal.find(dog.id) # Va returna un obiect Dog
    

Asocieri polimorfe

Asocierile polimorfe sunt folosite atunci când un model poate aparține diferitelor alte modele.

  1. Adăugarea coloanelor _id și _type în modelul asociat: De exemplu, dacă Comment poate aparține lui Article sau Photo:

    # migrare
    create_table :comments do |t|
      t.text :body
      t.references :commentable, polymorphic: true, null: false
      t.timestamps
    end
    
  2. Declararea asocierii în modele: În modelul Comment:

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

    În modelele 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. Utilizare:

    # consolă
    article = Article.create(title: "Sfaturi Rails")
    photo = Photo.create(caption: "Apus de soare frumos")
    
    article.comments.create(body: "Articol grozav!")
    photo.comments.create(body: "Fotografie frumoasă!")
    
    Comment.first.commentable # Va returna un Article
    Comment.last.commentable  # Va returna un Photo
    

Alegerea între STI și asocierile polimorfe depinde de structura datelor și de relațiile dintre modele. STI pentru relații "este-un" (Dog este un Animal), asocierile polimorfe pentru relații "are un" (Article are un Comment, Photo are un Comment, unde Comment poate aparține lui Article SAU Photo).