【问题标题】:Rails Generator Pass an Array of ArgumentsRails 生成器传递一组参数
【发布时间】:2026-02-09 09:00:01
【问题描述】:

我查看了有关如何创建自己的生成器的 rails casts 并阅读了许多堆栈溢出问题。基本上我想要做的是构建一个生成器,比如内置的 rails 迁移生成器,它接受attribute:type 之类的参数,然后根据需要插入它们。这是我现在的生成器代码。

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

基本上我想要它做的是生成一个视图文件,其中包含与参数一样多的行。所以传递rails g form products name:input amount:input other_attribute:check_box 会生成一个_form.html.erb 文件,内容如下:

<%= 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 %>

如何编写生成器以获取多个参数并根据这些参数生成多行?

【问题讨论】:

    标签: ruby-on-rails ruby code-generation simple-form


    【解决方案1】:

    构建表单生成器:$ 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
    

    测试

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

    结果

    # 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 %>
    

    【讨论】: