A dedicated Rails Controller with custom actions for your public static pages

In the last article about public static pages, we've seen the brute force approach of creating very static public pages in Rails: Just put them into the app/assets/public folder, together with your error pages, and link to them from the routes.

But what if you want to add a little tiny chunk of dynamicity to your page, and for example show
off a small sample of resources to users who haven't signed up to your page yet? Or you just want all the nice Rails helpers to be available on your "static" page.

Also, most probably you aren't a designer or you just don't have much time for creating a fresh new design for your static page. You just want to reuse your app's layout.

The challenge with public pages is that they are a kind of business and domain logic. And if you have worked with Rails before just a little, you'll know that Rails doesn't care about your feelings and business logic. It's for you to decide how to model and where to put it.

So naturally, there are tons of approaches and different places how to structure your business logic.

There are 2 major approaches:

  1. Create a public/static pages controller
  2. Make your public page a resource

In this article, we'll look at the most common one: Creating a public page controller.

Let's assume you have created an app that allows users to learn memory techniques. In this scenario, you might benefit from having a controller like that:

# public_pages_controller.rb
class PublicPagesController
  def home
    # Your fancy /home page might not be doing anything, or it might actually
    # let users subscribe for a newsletter or updates about your upcoming
    # product:  
  end

  def about
    # Your /about page might be super boring and static describing you and
    # your team...
  end

  def memory_palace_technique
    # Here you explain to your users what a memory palace is and how they can
    # create some in your app with an example:
    MemoryPalace.sample
  end

  def memory_major_system_technique
    # Another feature of your app might be to list a different memory technique.
    # In this case you showcase a sample of a different resource:
    Peg.where(type: "original", language: params["language"]).first
  end
end

With that you can just link to your pages from the routes like this:

# routes.rb
Rails.application.routes.draw do
  # Admin routes.
  # 
  # ...
  #
  # Logged in user routes.
  # 
  # ...
  # 
  # Public routes.  
  root 'pages#home'
  get '/about', to: 'public_pages#about'
  get '/contact', to: 'public_pages#memory_palace_technique'
  get '/help', to: 'public_pages#memory_major_system_technique'
  # ... More static pages like ToC and privacy pages ...
end

That's it. Just add your .html.erb views in the respective folder with the right name and you are done.

This looks like having all the static pages in one place, but it can create a bit of a design challenge once you start doing these dynamic things and start displaying samples based on some user input (which is not super static anymore, but it's public, and your "static" pages might evolve into something more alive and interactive).

In this case, trying to think of your public static pages as resources can improve your overall design and lead to better solutions. You will see this in action in the next article, where I will show you which design challenges I ran into and the advice I took that made the whole setup much nicer.