If you’re building a website, you’re no doubt going to want to add some dynamic content to it. In Ruby on Rails, this is a surprisingly easy task and can be set up in just a few minutes. No gems required.

To get started, first set up a Contents model:

rails g contents slug:string format:string title:string author:string body:text

Then modify the migration file that was created so it includes a default value for :format and has a unique index for :slug:

 1 # File: db/migrate/*_create_contents.rb
 2 
 3 class CreateContents < ActiveRecord::Migration
 4   def change
 5     create_table :contents do |t|
 6       t.string  :slug
 7       t.string  :format, default: "html"
 8       t.string  :title
 9       t.string  :author
10       t.text    :body
11       t.timestamps
12     end
13 
14     add_index :contents, :slug, unique: true
15   end
16 end

Now configure the Content model so it parameterizes the title into a slug, which is what we’ll be using for the URL to display the content. You’ll also need to set up the accessible fields, and validations:

 1 # File: app/models/content.rb
 2 
 3 class Content < ActiveRecord::Base
 4   attr_accessible               :title,
 5                                 :body,
 6                                 :author,
 7                                 :format
 8 
 9   validates_presence_of         :title,
10                                 :format,
11                                 :slug
12 
13   before_validation do
14     self.slug = self.title.parameterize
15   end
16 
17   def to_param
18     self.slug
19   end
20 end

Next create a controller that will render the requested Content:

 1 # File: app/controllers/contents_controller.rb
 2 
 3 class ContentsController < ApplicationController
 4   def show
 5     # Get the ID of the page being requested, defaulting to 'home'
 6     @id = params.fetch(:id, 'home')
 7 
 8     # Get the format of the requested content
 9     @format = params.fetch(:format, 'html')
10 
11     # Find the content by its slug and format
12     @content = Content.find_by_slug_and_format!(@id, @format)
13 
14     # Render the content inline
15     render inline: @content.body
16   end
17 end

Configure your app’s routes:

1 # File: config/routes.rb
2 
3 MyApp::Application.routes.draw do
4   root to: "contents#show"
5   get "contents/*id" => "contents#show"
6 end

Fire up the rails console and create some default content:

1 Content.create! format: 'html', title: 'Home Page', body: '<h1><%= @content.title %></h1>'

Now when you visit your app in the browser you’ll be presented with content that was pulled from the database and rendered by your application.

This is just a very brief example of how to set this up. There’s a lot more to take into consideration. For example, since you can execute ERB code in your site’s dynamic content using this method, you’ll need to take the necessary security measures in the controller to ensure that malicious code or rouge scripts could not be executed. Which means that, unless you are the only person who will be editing your site’s content, you will probably want to use something other than Rails default template renderer, such as Shopify’s Liquid template language, since it leaves your site open to too many vulnerabilities otherwise.

You’ll also need to set up the controller to edit the content from within the browser. I left that out of the above example for the sake of brevity, since it is very basic Rails code.

comments powered by Disqus