0

Rails 3 に存在するnumber_fieldフォーム ヘルパーを Rails 2.3.15 アプリに追加したいのですが、モジュールの拡張に問題があります。

これらは、Rails 3 から必要なメソッドです

class InstanceTag
    def to_number_field_tag(field_type, options = {})
        options = options.stringify_keys
        if range = options.delete("in") || options.delete("within")
          options.update("min" => range.min, "max" => range.max)
        end
        to_input_field_tag(field_type, options)
      end
end

def number_field(object_name, method, options = {})
        InstanceTag.new(object_name, method, self, options.delete(:object)).to_number_field_tag("number", options)
end

def number_field_tag(name, value = nil, options = {})
        options = options.stringify_keys
        options["type"] ||= "number"
        if range = options.delete("in") || options.delete("within")
          options.update("min" => range.min, "max" => range.max)
        end
        text_field_tag(name, value, options)
end

これを、アプリケーション ヘルパーに含めるモジュールに追加しています。to_number_field_tagクラスを開いてオーバーライドを追加するだけなので、メソッドは簡単です。

FormHelper モジュール メソッドで問題が発生しました。これは、祖先チェーンを完全に把握できず、オーバーライドのスコープを設定する方法がわからないためです。基本的にどうすればいいのかわからない。

4

1 に答える 1

1

上記の問題は、FormBuilder をオーバーライドしていなかったことです。これは、将来これが必要になる可能性がある人のためのソリューションです。

入力タイプを実装するだけでなく、type="number"すべての新しい HTML5 入力用の汎用ヘルパーを作成することにしました。このコードをapplication_helper.rbに含めるオーバーライド ファイルに配置します。

# file 'rails_overrides.rb`

ActionView::Helpers::InstanceTag.class_eval do
    def to_custom_field_tag(field_type, options = {})
        options = options.stringify_keys
        to_input_field_tag(field_type, options)
      end
end

ActionView::Helpers::FormBuilder.class_eval do
    def custom_field(method, options = {}, html_options = {})
        @template.custom_field(@object_name, method, objectify_options(options), html_options)
    end
end

# form.custom_field helper to use in views
def custom_field(object_name, method, options = {}, html_options = {})
    ActionView::Helpers::InstanceTag.new(object_name, method, self, options.delete(:object)).to_custom_field_tag(options.delete(:type), options)
end

# form.custom_field_tag helper to use in views
def custom_field_tag(name, value = nil, options = {})
    options = options.stringify_keys
    # potential sanitation. Taken from rails3 code for number_field
    if range = options.delete("in") || options.delete("within")
      options.update("min" => range.min, "max" => range.max)
    end
    text_field_tag(name, value, options)
end

次に、これをビューで使用するには:

<% form_for... do |form| %>
    <%= form.custom_field :user_age, :type=>"number", :min=>"0", :max=>"1000" %>
    <%= form.custom_field :email, :type=>"email", :required=>"true" %>
<% end %>

どちらが生成されますか<input type='number', and an <input type='email'

カスタム フォーム ビルダーがある場合は、それも展開/オーバーライドする必要があります。名前空間は異なる場合がありますが、ほとんどの標準は次のようになります。

MySpecialFormBuilder.class_eval do
    def custom_field(method, options = {}, html_options = {})
        ...custom form builder implementation
    end
end
于 2013-08-19T18:04:23.767 に答える