【问题标题】:simple_form accept a hash for collection inputsimple_form 接受集合输入的哈希值
【发布时间】:2019-03-20 22:21:06
【问题描述】:

当前行为

使用 simple_form 你需要传递一个数组:

<%= f.input :my_field, collection: [[true,"Yes"],[false,"No"]] %>

预期行为

如果能够传递一个散列会很好,所以你不需要对每个传递的散列执行 invert.sort。有没有办法为每个输入做到这一点?

<%= f.input :my_field, collection: {"true"=> "yes", "false"=>"No" } %>

是否可以在没有invert.sort?的情况下将哈希直接传递到输入中

【问题讨论】:

标签: ruby-on-rails simple-form ruby-on-rails-5.2 simple-form-for


【解决方案1】:

你可以添加你自己的助手my_simple_form_for来使用你自己的YourFormBuilder

module ApplicationHelper
  def my_form_for record, options = {}, &block
    options[:builder] = MyFormBuilder
    simple_form_for(record, options, &block)
  end
end

或者直接这样使用:

<%= simple_form_for @record, builder: MyFormBuilder do |f| %>

在您自己的构建器中,您可以覆盖input

class YourFormBuilder < SimpleForm::FormBuilder

  def input(attribute_name, options = {}, &block)
    options[:collection] = options[:collection].invert.sort if options[:collection].present? and options[:collection].kind_of? Hash
    super
  end

end

【讨论】:

    【解决方案2】:

    基于我们的earlier Q&A,您可以增强Hash 扩展以包含as_select_options

    module DropdownExt
    
      def self.extended(receiver)
    
        receiver.each do |k,v|
          define_method(k) do 
            v.is_a?(Hash) ? v.extend(DropdownExt) : v
          end
        end
    
        define_method(:as_select_options) do 
          unless receiver.values.map{|v|v.class}.include?(ActiveSupport::HashWithIndifferentAccess)
            receiver.invert.sort
          else
            []
          end
        end
    
      end
    end
    
    class Dropdowns
    
      class << self
    
        private
    
        def dropdowns_spec
          YAML.load_file("#{path}").with_indifferent_access
        end
    
        def path
          Rails.root.join("spec/so/dropdowns/dropdowns.yaml") # <== you'll need to change this
        end
    
      end
    
      dropdowns_spec[:dropdown].each do |k,v|
        define_singleton_method k do 
          v.extend(DropdownExt)
        end
      end
    
      %i(
        truck_model
        bike_model
      ).each do |to_alias|
        singleton_class.send(:alias_method, to_alias, :car_model)
      end
    
    end
    

    这会让你做这样的事情:

    Dropdowns.car_model.field1.as_select_options
     => [["false", "no"], ["true", "yes"]]
    

    或者,我想:

    <%= f.input :my_field, collection: Dropdowns.car_model.field1.as_select_options %>
    

    它不会避免invert.sort。但是,它确实把它埋了一点,并用一个方便的as_select_options 方法把它包起来。

    【讨论】:

      猜你喜欢
      • 2017-07-13
      • 1970-01-01
      • 2012-11-13
      • 2017-10-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-03-16
      相关资源
      最近更新 更多