Rails:如何为属性组合创建表单字段?

时间:2016-06-19 20:31:50

标签: ruby-on-rails forms ruby-on-rails-4 design-patterns

我有一个很多领域的模型,其中许多领域密切相关。

说我有模特:Fruit有attrs:fruit_type: ['apple', 'banana']fruit_color: ['red', 'green', 'yellow']is_rotten: ['true', 'false']

现在我想为这些模型创建一些超级用户友好的创建/编辑表单,用户可以在其中编辑属性。 Rails非常适合:

创建一个类似的表单:

= form_for @fruit do |f|
  = f.select :fruit_type, options_for_select(['apple', 'banana'])
  = f.select :fruit_color, options_for_select(['red', 'green', 'yellow'])
  = f.check_box :is_rotten
  = f.submit "save!"

将为您提供rails的所有巨大优势,使用非常有限的代码量自动呈现该属性当前正在使用的值等。

现在。实际上,如果这将是超级用户友好和快速使用,组合其中一些字段将更有意义,因此用户只需从组合列表中选择一个项目,然后生成关于模型的正确数据:

= form_for @fruit do |f|
  = f.select :fruit_color_and_fruit_type, options_for_select(['Yellow apple', 'Red apple', 'Green apple', 'Yellow banana'])
  = f.check_box :is_rotten
  = f.submit "save!"

然而,这不是直接从轨道支持的原因。那么,我可以使用什么模式来使这个游戏很好用rails'做事的标准方式(强大的参数,预先设定表格中的价值,属性质量分配等),所以我不必在任何地方进行黑客攻击和硬编码?

1 个答案:

答案 0 :(得分:0)

在控制器

您可以提交组合值,然后使用控制器中的逻辑将它们拆分为正确的属性。我认为这种方式更清洁,更可靠。

应用/模型/ fruit.rb

class Fruit < ActiveRecord::Base

  attr_accessor :fruit_color_and_fruit_type

  ...

end

应用/控制器/ fruit_controller.rb

class FruitController < ApplicationController

  ...

  def create
    attrs = fruit_params
    attrs[ :fruit_color ] = attrs[ :fruit_color_and_fruit_type ].split( ' ' )[ 0 ].downcase(  )
    attrs[ :fruit_type ] = attrs[ :fruit_color_and_fruit_type ].split( ' ' )[ 1 ].downcase(  )
    @fruit = Fruit.new( attrs )

    if @fruit.save
      flash[ :success ] = 'New fruit created.'
      redirect_to users_path
    else
      render :new
    end
  end

  ...

  private

    def fruit_params
      params.require( :fruit ).permit( 
        :fruit_color_and_fruit_type, 
        :is_rotten 
      )
    end
end

在表格

也可以提交预先格式化的信息,这样您就不必在控制器中弄乱它。只需使用隐藏的输入和一点JavaScript。

应用/模型/ fruit.rb

class Fruit < ActiveRecord::Base

  attr_accessor :fruit_color_and_fruit_type

  ...

end

应用/控制器/ fruit_controller.rb

class FruitController < ApplicationController

  ...

  private

    def fruit_params
      params.require( :fruit ).permit( 
        :fruit_color,
        :fruit_color_and_fruit_type, 
        :fruit_type,
        :is_rotten 
      )
    end
end

应用/视图/果/ new.html.haml

%script
    :plain
        $( document ).ready( function (  ) {
            // the ids used here are the ones automatically assigned by form_for.
            $( document ).on( 'change', '#fruit_fruit_color_and_fruit_type', function (  ) {
                var value = $( this ).val(  );

                $( '#fruit_fruit_color' ).val( value.split( ' ' )[ 0 ].toLowerCase(  ) );
                $( '#fruit_fruit_type' ).val( value.split( ' ' )[ 1 ].toLowerCase(  ) );
            } );
        } );

= form_for @fruit do | f |
    = f.hidden_field :fruit_color
    = f.hidden_field :fruit_type
    = f.select :fruit_color_and_fruit_type, options_for_select(['Yellow apple', 'Red apple', 'Green apple', 'Yellow banana'])
    = f.check_box :is_rotten
    = f.submit 'Save!'