Single Table Inheritance to refer to a child class with its own fields
The thing with single table inheritance is it is based on a single table model, not surprisingly, so you can't have different classes using different tables.
Typically the "Rails Way" is to bundle together all the possible fields that are required into a single table and use STI to handle the data mapping and validation issues for you. There are limits on what it can hide from the application, though, as generally a field being defined means it's usable by any of the classes bound to that table. Most people do not consider this to be an issue.
What you probably want to do is make a record that's joined in depending on the user type, for instance:
class User < ActiveRecord::Base
end
class AdminUser < User
belongs_to :admin_profile
end
class CommonUser < User
belongs_to :common_profile
end
This would require the users
table having an admin_profile_id
and common_profile_id
column where the admin_profiles
and common_profiles
tables contain the required additional fields.
The attributes in these tables can be mapped back into the base class using the delegate
method as required.
Moving the extra fields into a separate table may help compartmentalize things, but it also means reads will be slower because of the required join and the possibility of inconsistent records, due to one part being missing or out of date, is increased.
Generally you are okay loading all of the user-related fields into a single table even if many of these fields are not frequently used. The storage cost of a NULL field is typically low in the scheme of things and unless there are hundreds of these fields, the additional complexity exposed to the developer is minimal, a smaller price to pay than to have to create and reference records in pairs constantly.
How to make work single table inheritance and attr_accessible?
As discussed in the answer to Single Table Inheritance to refer to a child class with its own fields, ActiveRecord
's implementation of Single Table Inheritance does not involve additional tables. All subclasses share the same table and rely on a type
field to identify subclasses. That explains why your Provider
instances only contain the fields available in your users
table, including the type
field that Rails adds for the subclassing support. Your providers
table is unused.
Can model belong to STI child?
A better way to handle assocations and STI is to just setup the assocations to the base class:
class Place < ApplicationRecord
end
class SubPlace < Place
has_many :posts, foreign_key: 'place_id', inverse_of: 'place'
end
class AnotherKindOfPlace < Place
has_many :posts, foreign_key: 'place_id', inverse_of: 'place'
end
class Post < ApplicationRecord
belongs_to :place
end
This keeps things nice and simple since Post
does not know or care that there are different kinds of places. When you access @post.place
ActiveRecord reads the places.type
column and will instanciate the correct subtype.
If the base Post class also has the association you just write it as:
class Place < ApplicationRecord
has_many :posts, foreign_key: 'place_id', inverse_of: 'place'
end
Single Table Inheritance in Django
There are currently two forms of inheritance in Django - MTI (model table inheritance) and ABC (abstract base classes).
I wrote a tutorial on what's going on under the hood.
You can also reference the official docs on model inheritance.
Doctrine table class inheritance when one subclass has no extra attributes
You are using joined
inheritance model (class table inheritance), which uses a separate table for parent and each child. If you don't specify any fields in the child class, Doctrine will just create a table only containing ID field.
And a parent class can only use one type of inheritance, either class table inheritance or single table inheritance.
In that case, if you don't want to have a table with only id column in it, you need to change your data model.
Create Django abstract child model refering to the table of the parent model
OK, I finally found a solution my own answer: using Django proxy models to achieve single-table inheritance:
class Child(Parent):
def my_method(self):
return 'done'
class Meta:
proxy= True
very good answer on how to expand single-table inheritance to have child models identified as "distinct" of the Parent model, and between them: https://stackoverflow.com/a/60894618/12505071
Related Topics
Nested Form_For Singular Resource
Rails Cancan and State MAChine - Authorizing States
How to Get a Listing of Only Files Using Dir.Glob
How to Get Error Messages from Ruby Threads
Can You 'Require' Ruby File in Irb Session, Automatically, on Every Command
Ruby Getting the Longest Word of a Sentence
Generating a Race Condition with Mri
Find Both Pattern and Position of Multiple Regex Matches in Ruby
Argumenterror (Wrong Number of Arguments (Given 2, Expected 1)) After Updating to Ruby 3.0
Ruby Private Attr_Accessor and Unexpected Nil
Ruby on Rails - $ Rails Server Fails Because Uglifier Gem Could Not Be Found
How to Include Ё in [А-Я] Regexp Char Interval
How to Mock Super in Ruby Using Rspec
Ruby 'Gets' That Works Over Multiple Lines
How to Make Rake Db:Migrate Generate Schema.Rb When Using :SQL Schema Format