2012-08-27 2 views
61

Ho un modulo esistente che è legato a un modello denominato "Ordine", ma voglio aggiungere nuovi campi modulo che cattureranno informazioni sulla carta di credito come nome, numero cc, ecc. essere elaborati su un gateway di pagamento di terze parti.campi simple_form non relativi al modello

Ma dal momento che non voglio salvare le informazioni CC nel nostro database, non ci sono colonne corrispondenti nella mia tabella degli ordini. E questo mi dà un errore quando invio il modulo che quei campi di input della carta di credito non sono "parte" del modello dell'ordine.

+0

possibile duplicato di [Simple \ _form senza for (non model form)] (http://stackoverflow.com/questions/5181143/simple-form-without-for-non-model-form) – CharlesB

+1

Questa domanda non è un duplicato della domanda collegata sopra. Quello riguarda le forme intere non collegate ai modelli. Questo riguarda l'aver selezionato campi non collegati al modello del modulo. – depa

+2

Questo ti darebbe tutti i tipi di problemi con la conformità PCI ed è estremamente pericoloso !! Sebbene tu non stia salvando le informazioni CC nel tuo database, se lo stai inviando al tuo server tutti i dettagli saranno nei tuoi registri, se qualcuno ha accesso ai tuoi registri essi hanno accesso alle informazioni CC del client non crittografate. Evita assolutamente di inviare questi dati al tuo server. Se hai davvero bisogno di, guarda nella crittografia lato client (https://developers.braintreepayments.com/javascript+ruby/sdk/client/credit-cards). In caso contrario, utilizzare moduli di posta diretta o strumenti di rilascio di terze parti. In bocca al lupo! – Jay

risposta

34

È possibile utilizzare attr_accessor

class Order < ActiveRecord::Base 

    attr_accessor :card_number 


end 

Ora si può fare Order.first.card_number = '54421542122' o usarlo nel modulo o qualsiasi altra cosa che devi fare.

vedi qui per docs rubino http://www.ruby-doc.org/core-1.9.3/Module.html#method-i-attr_accessor e qui per un utile domanda StackOverflow What is attr_accessor in Ruby?

Non farlo confuso con attr_accessible! Difference between attr_accessor and attr_accessible

+1

Grazie! Ci proveremo. – zeratool

+0

Ho una domanda di follow-up, dopo aver inviato il modulo, sul controller, come posso "disinserire" quei campi relativi CC alla chiamata a "model.save" perché potrebbe generare errori? – zeratool

+1

potresti usare 'params.except (: card_number)' nel tuo controller. –

46

Se ho compreso correttamente la risposta, ciò che si vuole fare è spiegato nella pagina wiki ufficiale qui: Create a fake input that does NOT read attributes. È possibile utilizzare un campo non correlato a una colonna di database reale secondo il suggerimento di Edward, tuttavia non è necessario definire un attributo nel modello se il campo modulo non ha nulla a che fare con il modello.

In sintesi, il trucco spiegato nella pagina si definisce un ingresso personalizzato denominato 'FakeInput' e usarlo in questo modo:

<%= simple_form_for @user do |f| %> 
    <%= f.input :agreement, as: :fake %> 
    .... 

Non dimenticare di riavviare il server di binari dopo l'aggiunta/modifica di un ingresso personalizzato come ha commentato Fitter Man.

UPDATE: prega di notare che the official wiki page has updated e il codice di esempio nella pagina wiki non funziona per quelli che utilizzano le vecchie versioni di SimpleForm. Utilizzare il codice qui sotto invece se si verifica un errore come undefined method merge_wrapper_options for.... Sto usando 3.0.1 e questo codice funziona bene.

class FakeInput < SimpleForm::Inputs::StringInput 
    # This method only create a basic input without reading any value from object 
    def input 
    template.text_field_tag(attribute_name, input_options.delete(:value), input_html_options) 
    end 
end 
+0

Bello. Non l'avevo mai notato. – Edward

+2

Potrebbe essere necessario riavviare/ricaricare il server web per farlo prendere. –

+0

Per qualche motivo non funziona più. 'metodo non definito merge_wrapper_options per # ' – Trein

12

anche se si sta solo cercando di aggiungere qualcosa e lo fanno nella params, ma lasciando fuori hash del modello, si può solo fare FormTagHelpers. http://api.rubyonrails.org/classes/ActionView/Helpers/FormTagHelper.html

Esempio:

<%= simple_form_for resource, :as => resource_name, :url => invitation_path(resource_name), :html => {:method => :post} do |f| %> 
     <%= devise_error_messages! %> 

    <% resource.class.invite_key_fields.each do |field| -%> 
     <%= f.input field %> 
     <%= hidden_field_tag :object_name, @object.class.name %> 
     <%= hidden_field_tag :object_id, @object.id %> 
    <% end -%> 
23

Il modo migliore per gestire questo è utilizzare simple_fields_for modo:

<%= simple_form_for @user do |f| %> 
    <%= f.input :first_name %> 
    <%= f.input :last_name %> 
    <%= f.input :email %> 

    <%= simple_fields_for :other do |o| %> 
    <%= o.input :change_password, as: :boolean, label: 'I want to change my password' %> 
    <% end %> 
<% end %> 

In questo esempio, ho aggiunto un nuovo campo chiamato change_password che non fa parte del modello sottostante user.

Il motivo per cui questo è un buon approccio, è che ti permette di usare uno qualsiasi dei semplici form input/wrappers come campi. Non mi interessa la risposta di @baxang, perché non ti consente di utilizzare diversi tipi di input. Questo sembra più flessibile.

Tuttavia, nonostante ciò, per funzionare, ho dovuto passare :other a simple_fields_for.È possibile passare qualsiasi stringa/simbolo purché non ci sia un modello con lo stesso nome.

I.e. sfortunatamente non riesco a passare :user, in quanto simple_form proverebbe a creare un'istanza di un modello utente e avremmo di nuovo lo stesso messaggio di errore ...

+0

Non funziona per me. – varagrawal

+0

Funziona perfettamente, grazie. –

+0

Le risposte più semplici sono le migliori. Per me va bene. – emptywalls