web-dev-qa-db-ja.com

railsモデルに関連しないsimple_formフィールド

「注文」という名前のモデルに関連付けられている既存のフォームがありますが、サードパーティの支払いゲートウェイで処理される名前、cc番号などのクレジットカード情報をキャプチャする新しいフォームフィールドを追加したいです。

しかし、データベースにCC情報を保存したくないので、注文テーブルにはその対応する列がありません。そして、これらのクレジットカード入力フィールドが注文モデルの「一部」ではないというフォームを送信すると、エラーが発生します。

70
zeratool

Attr_accessorを使用できます

 class Order < ActiveRecord::Base

   attr_accessor :card_number


 end

これで、Order.first.card_number = '54421542122'またはフォームまたはその他の必要な操作で使用します。

Ruby docs http://www.Ruby-doc.org/core-1.9.3/Module.html#method-i-attr_accessor およびこちら便利なstackoverflowの質問 Rubyのattr_accessorとは?

Attr_accessibleと混同しないでください! attr_accessorとattr_accessibleの違い

40
Edward

私があなたの答えを正しく理解していれば、あなたがしたいことはここの公式wikiページで説明されています: 属性を読み取らない偽の入力を作成する 。 Edwardの提案により、実際のデータベース列に関係のないフィールドを使用できますが、フォームフィールドがモデルとは関係ない場合は、モデルに属性を定義する必要はありません。

要約すると、ページで説明されているトリックは、「FakeInput」と呼ばれるカスタム入力を定義し、次のように使用することです。

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

Fitter Manがコメントしたように、カスタム入力を追加/変更した後、Railsサーバーを再起動することを忘れないでください。

UPDATE:公式Wikiページが更新された であり、Wikiページのサンプルコードは、 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
47
baxang

これを処理する最良の方法は、次のように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 %>

この例では、基になるuserモデルの一部ではないchange_passwordという新しいフィールドを追加しました。

これが良いアプローチである理由は、単純なフォーム入力/ラッパーをフィールドとして使用できるようにするためです。 @baxangによる答えは気にしません。なぜなら、さまざまな種類の入力を使用できないからです。これはより柔軟なようです。

ただし、これが機能するには、:othersimple_fields_forに渡す必要があります。任意の文字列/シンボルを渡すことができます同じ名前のモデルがない限り

つまり残念ながら、simple_formはUserモデルをインスタンス化しようとするため、:userを渡すことができず、同じエラーメッセージが再び表示されます...

37
asgeo1

また、何かを追加して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 -%>
13
Richard Ortega

私は非常に単純な(そしていくぶん奇妙な)回避策を見つけました。

内部にvalueキーを持つinput_htmlオプションを追加するだけです。例えば:

= simple_form_for @user do |f|
  = f.input :whatever, input_html: {value: ''}

テスト済みのsimple_fromバージョン:3.2.1、3.5.1

1
user1201917