Laurens
Laurens

Reputation: 2088

Type classes in Rails

I have a Ruby 1.9.3 on Rails 3.2.2 application and I am dealing with a number of has_many associations that need to include a type. For example:

My problem is with naming all these classes. Right now the associations on the user are named Aircraft, License and Rating, but that still requires me to name the type-classes. I initially had them named AircraftType, LicenseType and RatingType but this smelled to me.

Right now I have all these type classes in a dedicated module Types, so my type classes are now named Types::Aircraft, Types::License and Types::Rating but I am not sure if this has me heading for trouble down the road given the questionable support for namespacing in Rails I keep hearing of.

Is there a convention or standard practice for this sort of problem?

Update:

Because the list of aircraft types is regularly updated, I need these to be in the database. While the license types and ratings change less frequently, I would still prefer them to be in the database if I need to add, change or remove any. This kind of rules out defining them statically in the classes themselves.

Upvotes: 0

Views: 178

Answers (1)

RadBrad
RadBrad

Reputation: 7304

You could put the types in the models as a class method, because they are so tightly associated with the model. Something like:

class Aircraft < ActiveRecord::Base
  def self.XTypes
     ['Cessna 172','Cessna 152','Boeing 747']
  end
end

Just don't use 'type', as rails has reserved that for single table inheritance, in fact 'Types' may even be dangerous, BUT, it would be nice to keep the attribute name the same for all of your models that have types, that at least opens up the possibility of DRYer code, you could possibly share some code between all the Models that have XTypes, like in a view helper that creates a select element for any model that has an XType.

So, typically you'd use XTypes like this:

<%= f.select 'xtype', Aircraft.XTypes %>

The larger the list of XTypes, and the more prone they are to revisions/additions/deletions, you should probably consider putting them in a separate model and link them up with a has_one relationship, but if they are fairly static, the above approach would probably be fine.

UPDATE:

I think Single Table Inheritance may be the ticket, either that or just a simple has_one relationship. But it sounds like you want to condense all these types into a single entity, so you may want STI

class mytype < ActiveRecord::Base; end
class AircraftType < mytype; end
class LicenseType < mytype; end

You just have to add a string attribute called 'type' in your mytype model, and fill it in with the values 'AircraftType' or 'LicenseType'. Now you have one model that can accommodate all of your types, i.e. if you're editing a license record, and you want a select element of LicenseTypes, you could do:

<%= f.select 'type', LicenceType.all().map {|t|, [t.id, t.description] }

If you were editing an aircraft:

<%= f.select 'type', AircraftType.all().map {|t|, [t.id, t.description] }

This assumes the base mytype model has an attribute 'description'

Upvotes: 2

Related Questions