Rails Generator Pass an Array of Arguments

1.5k views Asked by At

I've looked at the rails casts on how to create your own generator and have read a number of stack overflow questions. Basically what I am trying to do is to build a generator like the built-in rails migration generator where it takes arguments like attribute:type and then inserts them as necessary. Here is the code I have now for my generator.

class FormGenerator < Rails::Generators::NamedBase
  source_root File.expand_path('../templates', __FILE__)
  argument :model_name, :type => :string
  argument :attributes, type: :array, default: [], banner: "attribute:input_type attribute:input_type"
  argument :input_types, type: :array, default: [], banner: "attribute:input_type attribute:input_type"



  def create_form_file
    create_file "app/views/#{model_name.pluralize}/_form.html.erb", "


<%= simple_form_for @#{model_name.pluralize} do | f | %>
<%= f.#{input_type}  :#{attribute}, label: '#{attribute}' %>
<% end %>
"
  end
end

Essentially what I want it to do is generate a view file with as many lines as there are arguments. So passing rails g form products name:input amount:input other_attribute:check_box would generate a _form.html.erb file with the following:

<%= simple_form_for @products do | f | %>
    <%= f.input  :name, label: 'name' %>
    <%= f.input  :amount, label: 'amount' %>
    <%= f.check_box  :other_attribute, label: 'other_attribute' %>
    <% end %>

How would I write the generator to take multiple arguments and generate multiple lines based on those arguments?

1

There are 1 answers

0
Lam Phan On

build form generator: $ rails g generator form

# lib/generators/form/form_generator.rb
class FormGenerator < Rails::Generators::NamedBase
  source_root File.expand_path('templates', __dir__)

  argument :model_name, type: :string, default: 'demo'
  class_option :attributes, type: :hash, default: {}

  def build_form
    create_file "app/views/#{model_name.pluralize}/_form.html.erb", 
    "<%= simple_form_for @#{model_name.pluralize} do | f | %>" + "\n" +
    options.attributes.map { |attribute, type|
      "<%= f.#{type}  :#{attribute}, label: '#{attribute}' %> \n"
    }.join('') +
    "<% end %>"
  end
end

test

$ rails g form demo --attributes name:input, pass:input, remember_me:check_box

result

# app/views/demos/_form.html.erb
<%= simple_form_for @demos do | f | %>
<%= f.input,  :name, label: 'name' %> 
<%= f.input,  :pass, label: 'pass' %> 
<%= f.check_box  :remember_me, label: 'remember_me' %> 
<% end %>