Переопределение читателей атрибутов модели не влияет на поля ввода simple_form

Я использую simple_form и хочу переопределить считыватели для атрибутов модели.

Таким образом, следующее не работает

class C < ActiveRecord::Base

  # it has attribute named pack

  def pack
    "Some value"
  end

end

В поле зрения есть следующий код

<%= simple_form_for @c do |f| %>
  <%= f.input :pack %>
<% end %>

таким образом, он должен показать форму с полем ввода со значением "Некоторое значение", но он пуст. Почему не переопределяет работу с simple_form?

Ответ 1

Я понял это, мой комментарий был в основном правильным, simple_form опирается на помощники формы Rails, которые используют read_attribute для получения значения от объекта ActiveRecord, таким образом, считывая значение в базе данных и не используя ваш метод. Симптом стойкости/домена/презентации. Способ вокруг этого:

 <%= f.input :pack, :input_html => { :value => @c.pack } %>
 # or
 <%= f.input :pack, :input_html => { :value => f.object.pack } %>

Или, если вы хотите, чтобы это было по умолчанию, вы можете создать свой собственный построитель форм поверх simple_for, например:

# lib/my_form_builder.rb **

class MyFormBuilder < SimpleForm::FormBuilder                                                                                               
  def input(attribute_name, options={}, &block)                                 
    options[:input_html] ||= {}                                                 
    options[:input_html][:value] = object.send(attribute_name)                  
    super(attribute_name, options, &block)                                                          
  end
end

И в вашей форме:

<%= simple_form_for @c, :builder => MyFormBuilder do |f| %>
  <%= f.input :pack %>
<% end %>

** в Rails 3 Я не думаю, что lib добавлен в путь загрузки по умолчанию, поэтому вам может потребоваться добавить его и перезагрузить приложение или поместить его в app/models (отказ от ответственности не является хорошей идеей, lib лучше).

Ответ 2

В Rails 3.2, по крайней мере, он больше не использует read_attribute. Но если вы используете текстовое поле, для извлечения значения используется InstanceTag.value_before_type_cast. Это использует:

object.respond_to?(method_name + "_before_type_cast") ?
  object.send(method_name + "_before_type_cast") :
  object.send(method_name)

(где method_name - это имя атрибута в этом контексте)

Итак, если вы хотите убедиться, что форма использует ваш атрибут, добавьте следующий псевдоним:

  alias pack_before_type_cast pack

Это работает для меня, просто обязательно верните там строку...