2012-05-26 12 views
10

Sto usando simple_form e voglio sovrascrivere i lettori per gli attributi del modello.L'override dei lettori di attributi del modello non influisce sui campi di input simple_form

Così seguente non funziona

class C < ActiveRecord::Base 

    # it has attribute named pack 

    def pack 
    "Some value" 
    end 

end 

Tenuto viene seguente codice

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

quindi dovrebbe mostrare forma con il contenitore di ingresso avente valore "Alcuni valore", ma è vuota. Perché non sovrascrive il lavoro con simple_form?

+0

ho lo stesso problema, la mia ipotesi è 'simple_form', o più probabilmente rotaie formare aiutanti, usare' read_attribute' invece di ' S fine' per ottenere i valori di input dagli oggetti ActiveRecord. – Kris

risposta

12

L'ho capito, il mio commento era fondamentalmente corretto, simple_form si appoggia su help di guide Rails che usano read_attribute per ottenere il valore da un oggetto ActiveRecord leggendo il valore nel database e non utilizzando il metodo. Un sintomo di accoppiamento persistenza/dominio/presentazione. Il modo per aggirare questo è:

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

Oppure, se si desidera che questo comportamento di default di essere è possibile creare il proprio costruttore di form in cima simple_for quali:

# 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 

E nel modulo:

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

** in Rails 3 non credo lib si aggiunge al percorso di carico di default quindi potrebbe essere necessario aggiungere esso e si riavvia app o metterlo in app/models (la dichiarazione di non responsabilità non è una buona idea, la lib è migliore).

5

In Rails 3.2 almeno, non sta usando direttamente read_attribute più. Ma se stai usando un campo di testo, usa InstanceTag.value_before_type_cast per ritirare il valore. Questo utilizza:

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

(dove method_name è il nome dell'attributo in quel contesto)

Quindi, se si desidera fare in modo che il modulo usa i tuoi di accesso attributo, aggiungere il seguente alias:

alias pack_before_type_cast pack 

che funziona per me, basta assicurarsi per restituire una stringa lì ...

+0

ha funzionato anche per me. :) –

+0

Ha funzionato per me. Ho dovuto usare 'alias_method' perchè mi ero preoccupato –

Problemi correlati