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
— 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
Here are the steps we need to take:
Find the original template
These live in the
lib/rails/generators/erb/scaffold/templatesfolder of the railties gem. To find the path of the gem, we can run
bundle show railties. Alternatively we can run
bundle open railtiesand navigate to the
_form.html.erbfile. 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 into
lib/templates/erb/scaffold/_form.html.erbwithin 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.