REST and STI: one or many controllers?

Hi all !

I have ContactRoutes subclassed as PhoneContactRoute,
AddressContactRoute and so on. Now, I’m thinking about my
controllers, and I am wondering if I should be creating a single
ContactRoutesController or have many controllers, one per subclass.

What seems to be the general consensus as this time ?

Thanks !

François Beausoleil
http://blog.teksol.info/
http://piston.rubyforge.org/

On 31-Jan-07, at 10:23 PM, Francois B. wrote:

Hi all !

I have ContactRoutes subclassed as PhoneContactRoute,
AddressContactRoute and so on. Now, I’m thinking about my
controllers, and I am wondering if I should be creating a single
ContactRoutesController or have many controllers, one per subclass.

What seems to be the general consensus as this time ?

Thanks !

Good morning François.

My approach would be to build interfaces based on the model
abstraction - not on the specific storage implementation - especially
as the subclasses deviate.

If you were to use a single controller, then you’ll likely find
you’ll be passing params to indicate the specific class. With
separate controllers you can code the specific sub-class.

This has has the additional bonus if you change your Models (when we
get multiple table inheritance) your controller interface will not
change.

Cheers,
Jodi
General Partner
The nNovation Group inc.
www.nnovation.ca/blog

Hello Jodi,

2007/2/1, Jodi S. [email protected]:

My approach would be to build interfaces based on the model
abstraction - not on the specific storage implementation - especially
as the subclasses deviate.

I was leaning towards one controller per subclass, as you indicate.
As you said, the specific controllers will know what class to
instantiate, as they are responsible for one type only.

Thank you for your time !

François Beausoleil
http://blog.teksol.info/
http://piston.rubyforge.org/

Francois B. wrote:

As you said, the specific controllers will know what class to
instantiate, as they are responsible for one type only.

Thank you for your time !

I’ve gone with one controller for all the classes because in my case
there was so much similarity, and it seemed to make sense from the user
interface perspective. I had virtually no changes in the controller
(beyond being careful about whther I was referring to base_class or
class, and not much in the view either (a couple of different partials).
Most of the work about what behaviour was allowed and expected was
delegated down to the models, with the base_class defining default
behaviour and the individual models overriding it if necessary. Worked
for me, though I suspect wouldn’t be right in every case.
Just my $0.02
Chris

I have gone with one controller for each subclass.
I think they are different resources.
No problem until the next step.
I have had some troubles when I have nested resources for each of the
subclasses.
Consider that there is a has_many association between ContactRoutes and
some other class (say widgets, I can follow with a good example, due to
my poor level of english )

Which is the best way to make a WidgetController?
This will be a nested resource for the two subclasses of ContactRoutes ?
I have had troubles with it, in the views, when I want to link_to, back
to the named_url of the primary resource.
Which will be the best way to make this?.

Thanks
Juan M. Cervera

Hi !

2007/2/2, Juanma C. [email protected]:

This will be a nested resource for the two subclasses of ContactRoutes ?
I have had troubles with it, in the views, when I want to link_to, back
to the named_url of the primary resource.
Which will be the best way to make this?.

In my application, I have this:

class Party < AR::B
has_many :contact_routes, :as => :routable
end

class ContactRoute < AR::B
belongs_to :routable, :polymorphic => true
end

class PhoneContactRoute < ContactRoute
end

class AddressContactRoute < ContactRoute
end

So essentially, I have phones and addresses that belong to a party.
When addressing those resources, I want URLs like this:

/parties/1/phones/37
/parties/1/addresses
/parties/1/addresses/25;edit

In my case, I think it will be easier to not fight the flow. I can
always refactor common pieces of functionality into a base controller.

Bye !

François Beausoleil
http://blog.teksol.info/
http://piston.rubyforge.org/

Hi François,
I understand your case, it’s ok, but it is not exactly what I mean.
What about this:

class Person < AR::B
has many :phones
end

class Phone < AR::B
belongs_ot :person
end

class Customer < Person
end

Class Friend < Person
end

I have this in routes.rb
map.resources :people do |person|
person.resources :phones, name_prefix => “person_”
end
map.resources :customers do |customer|
customer.resources :phones, name_prefix => “customer_”
end
map.resources :friends do |friend|
friend.resources :phones, name_prefix => “friend_”
end

Now I can have these urls, nesting the phone resource in both customer
and friend resources:

/customer/1/phone/1
/friend/2/phone/3

I think this works well and go with the flow but, then, in the phone
controller, and the associated views, I would like to have a smart way
of knowing the type of the parent resource, and be capable of using a
named route to it, but I have to resort to make use of person[:type] in
a case sentence and use named paths like person_edit_phone_path, or
person_phone_path.

Oh well, now, writing it, it doesn’t look so bad.
The name_prefix is a necessity for avoiding urls collisions, and I
always will need a case sentence in the controller for redirecting to
the index view after a successful creation, update or destroy to
customer_path or friend_path based on person[:type]
I will leave the comment, maybe it can help someone.

Juanma