2012-08-27 45 views
61

我有一個與名爲'Order'的模型綁定的現有表單,但是我想添加新的表單域來捕獲信用卡信息,例如名稱,cc數等等在第三方支付網關上處理。rails simple_form字段與模型無關

但由於我不想在我們的數據庫中保存CC信息,因此在我的訂單表中沒有相應的列。當提交表單時,這些信用卡輸入字段不是訂單模型的「部分」,這給了我一個錯誤。

+0

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

+1

這個問題不是上述鏈接問題的重複。那一個是關於沒有連接到模型的整個表格。這是關於選擇未連接到表單模型的字段。 – depa

+2

這會給你所有與PCI合規問題,是非常危險的!儘管您不會將CC信息保存到數據庫中,但如果您將它提交給服務器,則所有的詳細信息都將存儲在您的日誌中,如果任何人有權訪問您的日誌,則可以訪問未加密的客戶端CC信息。你應該避免將這些數據提交給你的服務器。如果您真的需要,請查看客戶端加密(https://developers.braintreepayments.com/javascript+ruby/sdk/client/credit-cards)。否則,請使用直接發佈表格或第三方放置工具。祝你好運! – Jay

回答

34

您可以使用attr_accessor

class Order < ActiveRecord::Base 

    attr_accessor :card_number 


end 

現在你可以做Order.first.card_number = '54421542122'或在您的形式或其他任何你需要做的使用它。

在這裏看到紅寶石文檔http://www.ruby-doc.org/core-1.9.3/Module.html#method-i-attr_accessor 並在這裏進行了有益的計算器問題What is attr_accessor in Ruby?

不要把它混在一起attr_accessible! Difference between attr_accessor and attr_accessible

+1

謝謝!將嘗試。 – zeratool

+0

我在控制器上提交表單後,有一個後續問題,在調用'model.save'時如何「取消」這些CC相關字段,因爲它可能會引發錯誤? – zeratool

+1

您可以在控制器中使用'params.except(:card_number)'。 –

46

如果我正確理解你的答案,你想要做的是在這裏的官方維基頁面上解釋:Create a fake input that does NOT read attributes。根據Edward的建議,您可以使用與任何實際數據庫列無關的字段,但是如果表單字段與模型無關,則不需要在模型中定義屬性。

總之,關鍵在頁面說明的定義稱爲「FakeInput」自定義輸入,並使用它像這樣:

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

不要忘記添加/修改自定義輸入後重新啓動軌道服務器正如Fitter Man所評論的那樣。

更新:請注意,the official wiki page has updated和維基頁面上的示例代碼不適用於那些使用舊版本的SimpleForm。如果您遇到類似undefined method merge_wrapper_options for...的錯誤,請使用下面的代碼。我正在使用3.0.1,此代碼運行良好。

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

不錯。我從未注意到這一點。 – Edward

+2

您可能必須重新啓動/重新加載您的Web服務器才能啓用此功能。 –

+0

由於某種原因,它不再起作用。 'undefined method merge_wrapper_options for#' – Trein

12

此外,如果你只是想補充一點,並把它搬進params,但離開它了模型的哈希,你可以只是做FormTagHelpers。 http://api.rubyonrails.org/classes/ActionView/Helpers/FormTagHelper.html

實施例:

<%= 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

來處理這一點,最好的方法是使用simple_fields_for像這樣:

<%= 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 %> 

在本例中,我已經添加了一個新的領域稱爲change_password這是不部的底層user模型。

這是一個很好的方法,它的原因是它可以讓你使用任何簡單的表單輸入/包裝作爲字段。我不在乎@baxang的答案,因爲它不允許你使用不同類型的輸入。這似乎更靈活。

請注意,雖然爲此工作,我不得不通過:othersimple_fields_for。只要沒有同名的模型,您可以傳遞任何字符串/符號

I.e.不幸的是我不能通過:user,因爲simple_form會嘗試實例化用戶模型,並且我們會再次收到相同的錯誤消息...

+0

不適合我。 – varagrawal

+0

完美的作品,謝謝。 –

+0

最簡單的答案是最好的。適用於我。 – emptywalls