I'm trying to implement Multiple Table Inheritance with ActiveRecord. Looks like all the available gems are pretty old. Am I missing something? Is there any "native" way to implement this with activerecord?
I'm using Rails 3.2.3 and activerecord 3.2.1
Rails 6.1+ delegated type
Rails 6.1 added a "native" way to implement Multiple Table Inheritance via delegated type.
See the corresponding PR for details.
With this approach, the "superclass" is a concrete class that is represented by its own table, where all the superclass attributes that are shared amongst all the "subclasses" are stored. And then each of the subclasses have their own individual tables for additional attributes that are particular to their implementation. This is similar to what's called multi-table inheritance in Django, but instead of actual inheritance, this approach uses delegation to form the hierarchy and share responsibilities.
Single Table Inheritance (where each Car and Truck share one database)
class Vehicle < ActiveRecord
end
class Car < Vehicle
end
class Truck < Vehicle
end
In your case you are not sharing the database but rather the functions. You should then write a module and include it in each model
class Car < ActiveRecord
extend VehicleFinders
end
class Truck < ActiveRecord
extend VehicleFinders
end
module VehicleFinders
def find_purchased
#...
end
end
So in extend module's method are class method on that calling class.include module's methods are instance method for object of calling class
This might be a good read for you http://raysrashmi.com/2012/05/05/enhance-rails-models
Related
I have a class hierarchies that differ only in some attributes and i want to create classes that are a combination of class hierarchies (like uml picture) which can lead to exploded hierarchy.
is there any solution to this design? it is like decorator pattern but on attributes not on behavior. Is it possible to use decorator as an alternative to inheritance
It is possible.
What you need to do is invert the dependency of this hierarchy. In a language that supports Interfaces(like c#), you can create those structures and combine them to provide this behavior.
The "Combination" will be decorated by the Base class which inherits Combination Class and implements ChildClass1(Interface) and ChildClass2(Interface) for instance. Considering Base class as a Decorator. Check the Decorator Pattern in C# Here.
Another option is not using the Decorator at all, having Base Class, ChidClass1, 2 and 3 being Interfaces.
This is an opinion-based question, so chances are it will be deleted.
Let's say I have class Teacher and class Course. I want to create method GetCourseId(TeacherId) that will receive as input parameter a TeacherId and will return a CourseId.
Should this method be in class Teacher or class Course?
I guess my question is that if there's a method that can fall under any number of classes, where should it finally go? Is there some unspoken rule for that?
Thanks.
I've often seen a third class created to handle something like this, where a method requires knowing about 2 classes and it doesn't quite fit in either.
In this case, it'd be the creation of a CourseManager that could contain methods like GetCourseId, GetCourseByTeachers, AddCourse, and other 'admin' tasks.
Many of these would serve as a wrapper of sorts -- CourseManager.AddCourse would likely pass a lot of work off on the Course constructor.
Normally i define classes like Teacher, Course as java beans which just hold fields, getters/setters and some very basic methods which directly use the fields and don't include any business logic.
Based on the supported functionalities/features in my application, i create business/manager classes which implement my business through communicating with the other java beans.
So if i'm creating a simple course registration application for a university, I would define 3 java beans: Teacher, Course, Student in addition to some manager classes based on the features that i want to support in my application i.e. in our case RegistrationManager which would hold methods like: registerStudentInCourse(), getStudentCourses(), addCourseTeacher() ..
Please note that I'm just sharing my way of coding, people may or may not agree with it.
The simplest solution will be having a property like
private Course course
or
private Set<Course> courses
based on cardinality (OneToOne or OneToMany) in Teacher class. It could be ManyToMany as well depends on the requirement and data modeling. You can get or set course/s assigned to the teacher using getter/setter method.
Apart from this if the relation is bidirectional than you can have similar property in Course class. In case of bidirectional mapping you can have utility method like registerCourse in the Teacher class which will set proper relations between entities.
public boolean registerCourse(Course course){
this.course = course;
course.setTeacher(this);
}
You can have this kind of utility method in Course class as well.
Given that I have 3 classes Asset, AssetA, AssetB what is the proper way to structure inheritance when using the factory method?
Here is how I would like to use these classes:
Asset.new(data) should deterministically create either AssetA or AssetB depending on some flag present in data
Asset should also act as a super class in a sense that it's methods should also be present in AssetA and AssetB
I would create a base Asset class and have AssetA and AssetB inherit from it. The factory class should be a separate class - AssetFactory - with just one single responsibility - it should create new Asset object based on some conditions.
Are you confusing simple factory with Factory Method?
A simple factory is a class (e.g., AssetFactory) that creates instances of the Asset hierarchy (e.g., AssetA or AssetB).
Factory Method (Gang of Four) has two hierarchies, one of factories and products. I'm not sure how your problem relates to this.
In my model all the derived classes have the same ** persistent** attributes and methods as the base abstract class. There are some class specific attributes which aren't persisted and methods have different implementation.
Right now I have about 4 inheriting classes, and I will add more in the future. The nature of the application is that such classes may be added for different uses, so its impossible to know them in advance. The only given is that they will all share the same methods and persistent attributes. The is one column which will be used as discriminator.
I am struggling with strategy. Obviously I don't want to write a ClassMap for each derived class. In fact I's like the persistence layer to be completely ignorant of these derived classes. I am thinking of having the derived classes be able to be created off the base class and to return a base class.
I don't suppose I have any better option?
Your approach is flawed in that the persistence layer can not be ignorant about the subclasses, because it needs to know what the class is when loading/storing.
What you can do is use a convention-based mapping instead of an explicit one (Fluent has Automapping, and ConfORM is convention/override based only), so you don't have to write every classmap.
In ConfORM, it's as easy as saying, for example, orm.TablePerClass<TheBaseClass>(), then mapper.CompileMappingFor(TheBaseClassAndAllItsSubclasses), and you'll get the mappings without any additional effort.
I am designing a utility to backup applications.
The backup functionality will contain both common tasks to do (common code) and some unique steps. Am I on the right track by using an interface for the unique behaviour and an abstract base class for the common behaviour in common by all the children? Is there any downside to this approach? Anything better?
Thanks
If the base class actually implements some behaviour then I think it's called a non-abstract base class.
Anyway I think that's called Template method pattern: you may want to look that up in a dictionary of patterns (which should explain when it's appropriate, and reference any similar alternative patterns).
I wouldn't use abstract base classes to share common functionality, but only to express is-a relationships. If D derives from B, wherever B is expected, a D can come up. This is the criteria for using public inheritance.
You can use private inheritance though, but you are limited to derive from only one class in some languages.
Which brings us to the point to should be the first - you should think about responsibilites and encapsulate functionality wherever it belongs to, exposing interfaces (or pure abstract classes in C++) to clients, and implementing functionalities in concrete classes that derive from those interfaces.