1

とヘルパーdisabledに属性を追加するフォーム ビルダーを Rails で構築しようとしています。これは私のコードの簡略版です:text_fieldselect

class LabelFormBuilder < ActionView::Helpers::FormBuilder  
  %w[text_field select].each do |method_name|
    define_method(method_name) do |name, *args|
      super(name, :disabled => true, *args)
    end  
  end
end

text_fields属性は適切に追加されますが、selects少し複雑になり、undefined method merge for #<Array:0x10b5229a0>エラーが発生し続けます。

これは私のビューコードです(再び簡略化されています):

<%= f.label :name %>
<%= f.text_field :name %>      # works!

<%= f.label :person %>
<%= f.select(:person_id, current_user.person_names, :prompt => 'Please select...') %>  # does not work!

select上記のクラスの 4 行目をヘルパーでも動作させるにはどうすればよいですか?

助けてくれてありがとう!

4

1 に答える 1

2

selectforは、次のメソッドシグネチャでここActionView::Helpers::FormBuilderで定義されます

def select(method, choices, options = {}, html_options = {})

text_fieldforは、ここで次のメソッドシグネチャを使用して(動的に)ActionView::Helpers::FormBuilder定義されます

def text_field(method, options = {})

これは1つの問題です。あなたのコードは、Railsが期待しているものではないパラメータとして渡さ{ disabled: true }れています。choices

私が見る他の問題は、あなたの意図との私の混乱に関連しています

super(name, :disabled => true, *args)

ビューから渡されたオプションを無視してoptions、オーバーロードされたメソッドを明示的に作成しているためです。{ disabled: true }

各メソッドを個別にオーバーロードするのが最も簡単だと思います。

class LabelFormBuilder < ActionView::Helpers::FormBuilder  
  def text_field(method, options={})
    options.reverse_merge! disabled: true
    super(method, options)
  end

  def select(method, choices, options = {}, html_options = {})
    html_options.reverse_merge! disabled: true
    super(method, choices, options = {}, html_options = {})
  end
end

の使用に注意してくださいreverse_merge!。これはRailsメソッドでありHash、ハッシュ項目のデフォルト値を提供できます(上記のデフォルトオプションなど)。これにより、オーバーロードしているメソッドに他のオプションを渡すことができ、適切なデフォルトを提供しながら:disabled、ケースバイケースでオーバーライドすることができます(または呼び出し直接渡すdisabled: falseselecttext_field) 。

これはテストされていませんが、あなたが求めているものに近づくはずです。

于 2012-11-05T01:40:02.453 に答える