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
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.
Here are the steps we need to take:
-
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 runbundle show railties
. Alternatively we can runbundle open railties
and navigate to the_form.html.erb
file. Once we’ve found this, we’ll want to copy it. -
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 intolib/templates/erb/scaffold/_form.html.erb
within our application’s root. -
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.