Single Table Inheritance and Virtual Controllers
I have the following models: a "base" class, Event, with two descendants, PublicCourse and PrivateCourse. Although, data-wise, they are pretty similar, behaviour-wise they are quite different. So Single Table Inheritance (STI although that could mean something completely different) is the way to go. (The alternative, of course, is a mix-in - which in most cases is far more preferable to inheritance).
I also have a public_courses_controller and a private_courses_controller. As each needs their own user-interface, distinct from the other.
However, there are places in the user-interface where I am showing a list of Events and I wanted to link to them - either private or public. I started by writing a helper:
def event_link(event)
event.is_a?(PrivateCourse) ? link_to(h(event.title), private_course_path(event)) : link_to(h(event.title), public_course_path(event))
end
Meaning I could write views like so:
@events.each do | event |
event_link(@event)
end
However I didn't like it - the way events used a totally different link syntax to every other entity in my application.
So instead I created a "virtual" controller, events_controller, that has a single show action.
def show
@event = Event.find(params[:id])
@event.is_a?(PrivateCourse) ? redirect_to(private_course_path(@event)) : redirect_to(public_course_path(@event))
end
Now my view looks like
@events.each do | event |
link_to(h(event.title), event_path(event))
end
The upside - my views are consistent, regardless of entity. The downside - if you click that link it forces a database hit and a redirect. However, I'm not expecting 11000 requests per hour, let alone 11000 requests per second (this is a commercial service, not a social networking phenomena) - so I'll deal with the scaling issues if and when they happen
No comments:
Post a Comment