В моем приложении Rails у меня есть два класса:
UserPost
и GroupPost
(наследует от ApplicationRecord), что я хочу создать подклассы нового класса Post.
Что было бы лучшим способом добавить это?
Это так же просто, как создание класса вручную и добавление наследования, или могут возникнуть проблемы?
Я делаю предположение, что UserPost и GroupPost унаследованы от ActiveRecord::Base, т.е. вы хотите сохранить их в своей БД
Если у вас есть классы UserPost и GroupPost, которые наследуются от Post следующим образом, это называется наследованием одной таблицы.
class Post < ApplicationRecord
end
class GroupPost < Post
end
class UserPost < Post
end
Rails по умолчанию ожидает, что у вас будет столбец с именем «type» (можно указать любое другое имя) в таблице Posts. GroupPost и UserPost будут заполнять соответствующие значения в одной таблице, добавляя «GroupPost» или «UserPost» к типу. Вы можете прочитать об этом здесь
Rails также предоставляет вам возможность сделать родительский класс «абстрактным», то есть он не должен сохраняться в базе данных. Возможно, вы заметили это и в файле app/models/application_record.rb. Таким образом, родитель служит просто концепцией, к которой вы можете добавить общее поведение, ИППП не сработает. Для детей потребуются отдельные таблицы.
class ApplicationRecord < ActiveRecord::Base
self.abstract_class = true
end
Если вы планируете иметь отдельные таблицы для классов, я бы рекомендовал попробовать композицию вместо наследования с помощью примесей. В основном вы пишете общую функциональность в «модуле» и включаете ее в классы, которым нужна отдельная функциональность. Концерны — это хороший способ добавить методы класса, ассоциации и т. д., не полагаясь на загадочный синтаксис ruby. Рекомендую ознакомиться с документацией
module Fooable
extend ActiveSupport::Concern
included do |base|
scope :enabled, -> { where(enabled: true) }
has_many :boos, dependent: :destroy
end
class_methods do
def having_name
where('name ILIKE ?', "#{name}%")
end
end
def hi
return 'hi'
end
end
class UserPost < ApplicationRecord
include Fooable
end
UserPost.first.boos # relationship
UserPost.enabled # calling a scope
UserPost.having_name('name') # calling a class method
UserPost.new.hi #calling an instance method