Allow dynamic STI

I have a case when I want to use postgres table inheritance. I want my STI inheritance_column to be virtual. What is the reason to check for inheritance_column in the columns_hash?

https://github.com/rails/rails/blob/4-2-release_notes/activerecord/lib/active_record/inheritance.rb#L151

If we check only in the record (from the query result), then it would be possible to have STI based on virtual columns.

Regards!

I have a case when I want to use postgres table inheritance. I want my

STI inheritance_column to be virtual. What is the reason to check
for inheritance_column in the columns_hash?

https://github.com/rails/rails/blob/4-2-release_notes/activerecord/lib/active_record/inheritance.rb#L151

If we check only in the record (from the query result), then it would be
possible to have STI based on virtual columns.

Virtual in what sense?

AR assumes the type column exists in some queries. For example if you have

    Square < Polygon < AR::Base

then Square.count triggers

    SELECT COUNT(*) FROM "polygons" WHERE "polygons"."type" IN ('Square')

Can you make that work with your table definitions?

I have never used table inheritance in Postgres, but my understanding is
that that kind of logic is builtin. I mean, if I understand it correctly

    SELECT COUNT(*) FROM "squares";

would count squares and all their descendants. You need to pass ONLY to
opt-out.

My first impression (modulus, again, I have not used it) is that Postgres
table inheritance is fundamentally incompatible with STI, and could maybe
deserve its own plugin. I have seen

    https://github.com/ninjudd/multi_table_inheritance

but does not seem to have much activity.

By virtual we mean that we don’t have the ‘type’ column in the DB at all. We determine it runtime via scope from the query.

Here is an example https://gist.github.com/gudata/7ff43e3b6600408b1c1e

multi_table_inheritance is very old and probably is not addressing the same problem.

By virtual we mean that we don't have the 'type' column in the DB at all.

We determine it runtime via scope from the query.

Here is an example https://gist.github.com/gudata/7ff43e3b6600408b1c1e

I don't quite see that in core.

AR does not have as a goal to support "inheritance" in a generic way.
Rather, AR has STI baked in, where STI is a very concrete portable pattern:

    http://martinfowler.com/eaaCatalog/singleTableInheritance.html

I believe trying to generalize the implementation of STI to fit other
designs in would not be a good idea. The design of STI should model STI.

Rather, I see here a plugin that specifically models table inheritance as
done in Postgres.

multi_table_inheritance

<https://www.google.com/url?q=https%3A%2F%2Fgithub.com%2Fninjudd%2Fmulti_table_inheritance&sa=D&sntz=1&usg=AFQjCNEOoIsa4h8OtebcAb119NEEy0wPAw> is
very old and probably is not addressing the same problem.

Yeah it's old and talks about Rails 2.3 in the README. I mentioned the
plugin only because it might be relevant and a plugin author could perhaps
check the implementation and see if they could copy some idea from it.

Doesn’t matter if the column comes statically or dynamically. The presence of the “type” virtual-column in the record should be enough.

record[inheritance_column].present?

instead of

record[inheritance_column].present? && columns_hash.include?(inheritance_column)

What do you think?

Doesn't matter if the column comes statically or dynamically. The presence

of the "type" virtual-column in the record should be enough.

record[inheritance_column].present?

instead of

record[inheritance_column].present? && columns_hash.include?(
inheritance_column)

What do you think?

AR assumes the column exists. STI needs the column to perform certain
queries related to the hierarchy as I showed before.

If AR cannot assume the column exists, then we need to introduce logic to
account for that in those queries, and so on. The design deviates. There's
no need for the design to deviate, AR models STI and STI has a type column.

I see your point that Rails is following the STI pattern.

However I can’t see why the column should be static in the schema and not to use the virtual one. I will have to spare some time to work on this to find out whats going to happen.

Thank you!

I see your point that Rails is following the STI pattern.

However I can't see why the column should be static in the schema and not
to use the virtual one. I will have to spare some time to work on this to
find out whats going to happen.

I would suggest a change of perspective, really.

Your application is not using a "dynamic STI". It is using Postgres true
table inheritance. Everything is different, tables are different,
attributes are different, queries are different.

In my view, it makes no sense to hack STI in AR to be able to support
something that is not STI.

Instead of doing that, it would be better to implement support for Postgres
table inheritance as is. The abstractions and API should reflect Postgres
table inheritance.