Daniel Fone

Ruby/Rails Engineer

Customising Scaffold Views in Ruby on Rails

In Rails 3.0 and above, generators don’t just look in the source root for templates, they also search for templates in other paths. And one of them is lib/templates

RailsGuide on Generators

This fact makes it very easy for us to change the views that are generated when we run rails generate scaffold .... Let’s say we want to change the scaffold’s form template so that it uses a select box for a belongs_to relationship.

select box

Here are the steps we need to take:

  1. Find the original template

    These live in the lib/rails/generators/erb/scaffold/templates folder of the railties gem. To find the path of the gem, we can run bundle show railties. Alternatively we can run bundle open railties and navigate to the _form.html.erb file. Once we’ve found this, we’ll want to copy it.

  2. Copy it into our application

    As quoted above, generators will search for templates in lib/templates. For this template, we’ll need to copy it into lib/templates/erb/scaffold/_form.html.erb within our application’s root.

  3. Change the template

    At this point, we can make whatever changes we like!

By way of illustration, here’s one way to use a select box for a belongs_to relationship.

--- lib/templates/erb/scaffold/_form.html.erb
+++ lib/templates/erb/scaffold/_form.html.erb
@@ -23,7 +23,7 @@
 <% else -%>
   <%- if attribute.reference? -%>
     <%%= f.label :<%= attribute.column_name %> %><br>
-    <%%= f.<%= attribute.field_type %> :<%= attribute.column_name %> %>
+    <%%= f.collection_select :<%= attribute.column_name %>, <%= attribute.name.camelize %>.all, :id, :name, prompt: true  %>
   <%- else -%>
     <%%= f.label :<%= attribute.name %> %><br>
     <%%= f.<%= attribute.field_type %> :<%= attribute.name %> %>

I’ve uploaded an example app to github, where you can see the customised template in full and also the view it generates.

Now when we run rails generate scaffold user name:string user_type:references, our form will use a helpful select box instead of an empty text field.

Edit: This question was originally prompted by a comment on another post, referencing a StackOverflow question.

comments powered by Disqus