7

Using the ActiveAttr:

class Filter
  include ActiveAttr::Model
  attribute term
  # Overriding to_key, to_param, model_name, param_key etc doesn't help :(
end

class SpecialFilter < Filter
end

How do I override the ActiveModel to generate the (same) predefined input names for all subclasses?

= form_for SpecialFilter.new, url: 'xx' do |f|
  = f.text_field :term

So instead of <input name='special_filter[term]' /> I need to get <input name='filter[term]' />

NOTE: The scenario is way much more complicated (with simple_form and radios/checkboxes/dropdowns etc), so please do not suggest to change the name of the class or similar workarounds. I really do need to have the consistent name to be used by the form builder.

Dmytrii Nagirniak
  • 23,696
  • 13
  • 75
  • 130

2 Answers2

8

Try this :

= form_for SpecialFilter.new, as: 'filter', url: 'xx' do |f|
  = f.text_field :term
ddb
  • 1,416
  • 11
  • 17
  • Thanks. That does the job. I'm still curious how to do it on the model (what do we need to override from ActiveModel?) – Dmytrii Nagirniak Sep 07 '12 at 07:34
  • I doubt this is happening at ActiveModel level. It seems to be at a form_helper level. See https://github.com/rails/rails/blob/beba8267c96a3dbc1f505ecc099dbf14db8dde4c/actionpack/lib/action_view/helpers/form_helper.rb on how exactly the form is generated. – ddb Sep 07 '12 at 07:40
  • actually the default is on ActiveModel level, see https://github.com/rails/rails/blob/beba8267c96a3dbc1f505ecc099dbf14db8dde4c/actionpack/lib/action_view/helpers/form_helper.rb#L369 – mkk Apr 07 '14 at 10:22
6

As Divya Bhargov answered, if you take a look at the source code you'll find out the internal call stack should end up like below.

 # actionpack/lib/action_view/helpers/form_helper.rb
 ActiveModel::Naming.param_key(SpecialFilter.new)

 # activemodel/lib/active_model/naming.rb 
 SpecialFilter.model_name

So, if you really want to do it in your model level, you need to override the model_name to your class.

class SpecialFilter < Filter
  def self.model_name
    ActiveModel::Name.new(self, nil, "Filter")
  end
end    

The parameter for this ActiveModel::Name initializer is klass, namespace = nil, name = nil.

But model_name is also used somewhere else such as error_messages_for, so do use this with care.

kinopyo
  • 1,667
  • 3
  • 19
  • 26