Forum: Ruby on Rails One Controller, many viewing platforms...

Announcement (2017-05-07): www.ruby-forum.com is now read-only since I unfortunately do not have the time to support and maintain the forum any more. Please see rubyonrails.org/community and ruby-lang.org/en/community for other Rails- und Ruby-related community platforms.
Collin M. (Guest)
on 2007-07-26 04:13
(Received via mailing list)
At our office we're building an app with some CMS-like qualities.

We have the requirement of serving to multiple platforms. We can strip
enough information out of the Headers to determine which platform a
request comes from.

Keeping with best practices we don't want to add any controllers for
this View problem. This should keep things nicely separated and
provide the benefit of all devices accessing the same URLs.

The structure of our view folders then looks like this:

\views
  \some_controller
    \platform_one
    \platform_two
    \platform_three

The problem now is to get get rails to go from this:

GET .../some_controller/
>> Rails renders .../views/some_controller/index.rhtml

to this:

header indicating platform_one
GET .../some_controller/
>> Rails renders .../views/some_controller/index.rhtml

A first attempt at such a solution rendered the following:

class ApplicationController < ActionController::Base
  private

  # This method is stolen from ActionController::Base
  # The only additon is "+ platform"
  def controller_path
    self.class.name.gsub(/Controller$/,'').underscore + platform
  end

  def platform
    ## This method returns a string derived from the request
    ## This string will be added to the controller_path used to find
templates
  end

  ## default_template_name and template_path_includes_controller? have
been
  ## copied from ActionController::Base

  ## There is one small change.
  ## references to "self.class.controller_path" have been swapped for
"controller_path"
  def default_template_name(action_name = self.action_name)
    if action_name
      action_name = action_name.to_s
      if action_name.include?('/') &&
template_path_includes_controller?(action_name)
        action_name = strip_out_controller(action_name)
      end
    end
    "#{controller_path}/#{action_name}"
  end

  def template_path_includes_controller?(path)
    controller_path.split('/')[-1] == path.split('/')[0]
  end
end

By overriding Rails where it builds a templates file path string we
can have platform specific views for our controllers without changing
individual controller code.

This solution is by no means tested, final or complete, just a peek
into what can be done.

A concern was raised in the office:

The performance hit taken checking the platform with every request.

I think the hit is negligible and will scale linearly. Still, should
that become an issue the platform can be worked into the session and
care can be taken that the platform-aware controller path will not be
generated more than once per request

I brought this to the mailing list in hopes of getting some feedback.

We are early in looking into filling this requirement and would be
overjoyed if a solution already exists or if there is another path to
take toward it.

Does anybody have any thoughts, negative or positive about this?
Rusty B. (Guest)
on 2007-07-26 08:38
(Received via mailing list)
On Jul 25, 8:12 pm, Collin M. <removed_email_address@domain.invalid> wrote:
> A concern was raised in the office:
>
> The performance hit taken checking the platform with every request.
>
> I think the hit is negligible and will scale linearly. Still, should
> that become an issue the platform can be worked into the session and
> care can be taken that the platform-aware controller path will not be
> generated more than once per request

Unless your platform method is time-consuming, storing it in the
session won't gain you anything.

A good measurement for "time-consuming" would be to compare it to a
database query.  More than likely it is faster than a database query.
Therefore you are better off reducing database queries than worrying
about to storing and reading the platform from the session.

~Rusty
This topic is locked and can not be replied to.