2012-05-26 18 views
10

Estoy usando simple_form y quiero sobrescribir los lectores para los atributos del modelo.Alterar los lectores de atributo de modelo no afecta a los campos de entrada de simple_form

De este modo siguiente no funciona

class C < ActiveRecord::Base 

    # it has attribute named pack 

    def pack 
    "Some value" 
    end 

end 

En vista no está siguiendo el código

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

por lo que debe mostrar la forma con la caja de entrada que tiene el valor "Algunos de valor", pero que está en blanco. ¿Por qué no anula el trabajo con simple_form?

+0

tengo el mismo problema, mi conjetura es 'simple_form', o los carriles más probables formar ayudantes, usar' read_attribute' en lugar de ' s end' para obtener los valores de entrada de los objetos ActiveRecord. – Kris

Respuesta

12

Me di cuenta de esto, mi comentario fue básicamente correcto, simple_form se apoya en Rails desde helpers que usan read_attribute para obtener el valor de un objeto ActiveRecord leyendo el valor en la base de datos y no usando su método. Un síntoma de persistencia de acoplamiento/dominio/presentación. La forma de evitar esto es:

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

O si desea que este comportamiento por defecto a ser usted puede crear su propio constructor de la forma en la parte superior de simple_for tales como:

# 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 

Y en su formulario:

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

** en Rails 3 no creo lib se añade a la ruta de carga por defecto así que puede ser que necesite para agregarlo y reiniciar la aplicación o ponerlo en app/models (no es una buena idea, lib es mejor).

5

En Rails 3.2 al menos, ya no está utilizando read_attribute directamente. Pero si usa un campo de texto, usa InstanceTag.value_before_type_cast para recuperar el valor. Esto utiliza:

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

(donde method_name es el nombre del atributo en ese contexto)

Así que si desea asegurarse de que la forma de acceso utiliza su atributo, agregue los siguientes alias:

alias pack_before_type_cast pack 

que funciona para mí, sólo asegúrese de devolver una cadena allí ...

+0

Funcionó para mí también. :) –

+0

funcionó para mí. Tuve que usar 'alias_method' porque yo estaba preocupado –

Cuestiones relacionadas