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
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
:format and has a unique index for
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
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.