Model Inheritance, Mixins and Database design

I’m trying to understand how best to use inheritance and wonder if
Rail’s Single Table Inheritance model too restricting.

I have a model Companies who provide 1+ Services (HABTM relationship).

I assume the best way to represent this is with a series of child models
representing each type of service : ServiceType < Company.

I want to return lists of companys for each service and then link to
show more details about them.

With the show method inherited from the Companies controller though
changing the :id on the end of the url displays the next record in the
companies table whereas I want to display the next company that also has
that service available.

I was wondering a number of things:

1/ Should be overloading the find method in the ServiceType models.

2/ a/ Should I be trying to inherit the View for Company for ServiceType
b/ by invoking Ruby’s super keyword somehow.

3/ Would it be better to have individual db table representing each
ServiceType
will the extra properiies that each ServiceType has in addition to the
inherited Company properities require this

_tony

Anthony

> I have a model Companies who provide 1+ Services (HABTM 

relationship).
> I assume the best way to represent this is with a series of child
models
> representing each type of service : ServiceType < Company.

I don’t understand your reasoning for using STI in this simple case.
You’d be better served by a plain and standard habtm

 Company
     has_and_belongs_to_many :services

 Service
     has_and_belongs_to_many :companies

That would offer you simple access and manipulations :

 ikea = Company.find_by_name "ikea"
 is = ikea.services

 fs = Service.find_by_description "furnitures selling"
 companies_selling_furnitures = fs.companies

Alain

 Company
     has_and_belongs_to_many :services

 Service
     has_and_belongs_to_many :companies

This is what I started with.

That would offer you simple access and manipulations :

 ikea = Company.find_by_name "ikea"
 is = ikea.services

 fs = Service.find_by_description "furnitures selling"
 companies_selling_furnitures = fs.companies

How to I access
company_selling_furniture.details

If I simply use an :id to have a url like

/companies/show/3

Then someone could just alter the url to

/company/show/4

which might not be a company selling furniture

But I also have access the additional properties of each service

company_selling_furniture.tables_for_sale

I’m trying to grasp how all the best practice concepts interlock

I’d assumed I should be generating models like

SellingFurnitureCompany < Company

MakingFurnitureCompany < Company

DeliveryCompany < Company

Is this not the right approach ? Its just in the Pickaxe book they give
the example of

JukeBoxSong < Song
KarokeSong < Song

I assumed I should adopt a similar methodology.

_tony

Anthony G. wrote:

If I simply use an :id to have a url like

/companies/show/3

Then someone could just alter the url to

/company/show/4

which might not be a company selling furniture

But I also have access the additional properties of each service

company_selling_furniture.tables_for_sale

I’m trying to grasp how all the best practice concepts interlock

I’d assumed I should be generating models like

SellingFurnitureCompany < Company

MakingFurnitureCompany < Company

DeliveryCompany < Company

Is this not the right approach ? Its just in the Pickaxe book they give
the example of

JukeBoxSong < Song
KarokeSong < Song

I assumed I should adopt a similar methodology.

_tony
This sounds like the right way to it, but what do you mean about the
id’s. Can you explain further?

joey__
http://www.feedreed.com

On 3/5/06, Anthony G. [email protected] wrote:

so we have
they shouldn’t.
http://lists.rubyonrails.org/mailman/listinfo/rails

If you want to restrict users from viewing certain objects, you can
build in an authentication system. Rails Recipes has a nice chapter
on it. This would require you to do something like
class User < ActiveRecord::Base
has_one :company
end

class Company < ActiveRecord::Base
belongs_to :user
end

Then in your list controller you do

def list
@services = session[:user].company.services
end

Since you’re accessing it all through the model, it’s protected (you
still have to write the auth code of course, but that’s simple).

I highly recommend picking up Rails Recipes, it has a lot of stuff
you’ll use.

Pat

If you want to restrict users from viewing certain objects, you can
build in an authentication system.

You’ve misunderstodd the issue.
I’m trying to understand why how child classes and inheritance interact
in the rails framework.

_tony

This sounds like the right way to it, but what do you mean about the
id’s. Can you explain further?

Its the way Rails does its routing by default…
:controller/:action/:id

In the list view its

/servicetype/list

in the show view its

/company/show/1

Now /servicetype/list will generate a list of links that point to the
show controller passing also an :id value

the value :id that Rails generates points to the primary key of the
record in the companies table

so we have

<a href=/company/show/2">FirstCompanyWithThisServiceType
<a href=/company/show/5">SecondCompanyWithThisServiceType

clicking on the first link goes to a url
/company/show/2
that invokes the :controller => company, the :action => show and :id =>
2

if edit the url to /company/show/3 they’ll see the details of a company
they shouldn’t.

_tony

I was responding to that. If I misinterpretted it, please explain it
better. The only way I can interpret that is “Users should not be
able to see the details of arbitrary companies.”

Keep in mind the thread is about inheritance and how it works with ORM.

The parent class maps to a table, an instance of that class mapping to a
record in that table. The default list and show actions use :id to pick
out a record in the table by its primary key.

Now a child class maps to the same table as their parent but the
instance only maps to records based on particular criteria. It this
situation using the combination of the show action and :id needs to be
restricted from showing records not belonging to that child.

To try and keep the thread on track the things I asked originally asked
were:

1/ Should I be overloading the find method in the ServiceType models.

2/ a/ Should I be trying to inherit the View for Company for ServiceType
b/ by invoking Ruby’s super keyword somehow.

3/ Would it be better to have individual db table representing each
ServiceType
will the extra properiies that each ServiceType has in addition to the
inherited Company properities require this

_tony

On 3/5/06, Anthony G. [email protected] wrote:

If you want to restrict users from viewing certain objects, you can
build in an authentication system.

You’ve misunderstodd the issue.
I’m trying to understand why how child classes and inheritance interact
in the rails framework.

“if edit the url to /company/show/3 they’ll see the details of a
company they shouldn’t.”

I was responding to that. If I misinterpretted it, please explain it
better. The only way I can interpret that is “Users should not be
able to see the details of arbitrary companies.”

Pat