Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

rails: create scaffold for models to inherit from superclass?

I'm new to Rails, still getting my feet wet, so please pardon me if this is either trivial or "the wrong way" to do things.

I'd like to create a superclass for some scaffolded models. For example, I'd like to create a scaffold for Men and for Women, but I want them both to inherit from a People superclass; Men and Women would inherit fields like height and weight from the People class.

Where/how do I define this People superclass? How do I define the subclasses Men and Women via scaffolding?

like image 222
aljabear Avatar asked Apr 06 '13 16:04

aljabear


2 Answers

Usually I do something like:

rails g scaffold People type:string name:string birth:date height:integer

class People < ActiveRecord::Base
end

Important use the reserved word 'type'! That's where the table will keep which type the class is. Run the migration.

So, for the the subclasses you can do:

rails g scaffold Men --parent=People

resulting Men:

class Men < People
end

Same for Women:

rails g scaffold Women --parent=People

Resulting

class Women < People
end

No migration will be generated for the subclasses. I'm not sure but this approach only works for STI.

Hope it, helps!

like image 152
Casé Oliveira Avatar answered Oct 22 '22 03:10

Casé Oliveira


This is something I've thought about doing with my application. I haven't done it yet, and I wouldn't recommend it if you are new to rails. I would either make separate models entirely, or make one model, and have the attribute gender, which should be either a 0 or a 1, and then make a method that returns the string for the corresponding gender.

EDIT

So I opened up the rails console, and from what I could see, it is possible totally possible, all you need to do is declare the class, and if you want to use different tables, set_table_name

class This < That
  set_table_name :this
end

class There < This
   set_table_name :there
end

Or you could use one table, but if your trying to stay DRY, I would use two.

If you want to use the scaffold generator, you will have to run the typical rails g scaffold Men for each class you want views for (men and women). The model that this generates inherits from the ActiveRecord::Base class. The inheritance marker is the less than symbol (<).

# THESE WILL BE THE DEFAULT GENERATED MODELS
class Men < ActiveRecord::Base

end

class Women < ActiveRecord::Base

end

You will then manually create the super class User

class User < ActiveRecord::Base

end

and then edit the Men and Women models to inherit from User

# men.rb
class Men < User
end

# women.rb
class Women < User
end

lets say you wanted to subclass with one table, you could would right the migrations for that table, and then add the attr_accessible to the appropriate subclass.

attr_accessible is a rails security feature. It determines which attributes may be set in mass assignment. Anything related to security, site rank, etc. should not be accessible.

Example:

attr_accessible :favorite_food, :interests, :password, :email # THIS IS GOOD

attr_accessible :admin, :has_access_to_missile_launch_codes # THIS IS BAD

because then someone could undermine your security system by passing

params => { :man => { :admin => true }}

The main point is that using these attr_accessible will determine which type of user can set what. Obviously you can DRY this up by putting shared features in the super-class. Hope this helps

You should also read about the super keyword, and the self keyword. If your running an inherited setup you will eventually want to use these.

like image 24
OneChillDude Avatar answered Oct 22 '22 04:10

OneChillDude