Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

In Ruby on Rails, if we generated a model "Animal", and now want to have "Dog", how should we do it?

say, if we generated a model

rails generate model animal name:string birthday:date

and now we want to create other model to inherit from it (such as Dog and Cat), should we use rails generate model again or just add the files ourselves? How do we specify Dog should inherit from Animal if we use rails generate model?

I think if we use rails generate model instead of adding the model files ourselves, there will be unit test files and fixture files created for us as well. A migration file is also added, except if it is using MongoDB, then there will be no migration file.

like image 509
nonopolarity Avatar asked Aug 31 '10 21:08

nonopolarity


People also ask

What is a subclass in Ruby?

Sub class: This is the class that is derived from the parent class. It is also known as a subclass or derived class or child class. You can also add its own objects, methods, along with the base class methods and objects, etc. Note: By default, every class in Ruby has a Super class.

What is the use of model in Rails?

In simple terms, models are Ruby classes that can holds value of a single row in a database table. Since they all inherit ActiveRecord::Base through ApplicationRecord class, they are equipped with all the ActiveRecord methods which enables them to interact with the database.


2 Answers

If the Dog, Cat and other subclasses you are planning are not going to diverge away from Animal model, you can STI (Single Table Inheritance) pattern here.

To do that, add a String column to Animal. And then you can have:

class Dog < Animal
end

class Cat < Animal
end

>> scooby = Dog.create(:name => 'Scooby', :date => scoobys_birthdate)
=> #<Dog id: 42, date: "YYYY-MM-DD", type: "Dog">

To generate model Dog

$ script/generate model Dog --skip-migration

And then change (usually app/models/dog.rb):

class Dog < ActiveRecord::Base

to

class Dog < Animal
like image 94
Swanand Avatar answered Oct 09 '22 12:10

Swanand


As far as I know you can't specify a superclass when generating a model. However, generators are only a stepping stone to creating your classes. You can generate the model class as normal and simply change the superclass in the generated model file. There are no other places that the inheritance relationship has to be specified for the generated files to work (the fixtures and unit tests for example don't specify super- or subclasses).

So:

script/generate model Dog

Then change:

class Dog < ActiveRecord::Base

to:

class Dog < Animal

If you want to generate a model that will inherit from Animal using single table inheritance then you may want to specify --skip-migrations on the script/generate call (though you may want a migration to add e.g. dog-specific columns to the animals table and you will need to add a type column of type string to the animals table).

like image 29
Shadwell Avatar answered Oct 09 '22 10:10

Shadwell