рейки просто_форма поля, не пов'язані з моделлю


74

У мене є існуюча форма, яка прив’язана до моделі з назвою „Замовлення”, але я хочу додати нові поля форми, які будуть фіксувати інформацію про кредитну картку, таку як ім’я, номер копії та ін., Що оброблятиметься на сторонній платіжний шлюз.

Але оскільки я не хочу зберігати інформацію про CC у нашій базі даних, у моїй таблиці замовлень немає відповідних стовпців. І це призводить до помилки при поданні форми, що ці поля введення кредитної картки не є «частиною» моделі замовлення.


можливий дублікат Simple_form без for (
немодель

1
Це питання не є дублікатом вищезв’язаного питання. Цей стосується цілих форм, не пов’язаних із моделями. Це стосується того, що вибрані поля не підключені до моделі форми.
Марсело Де Поллі

2
Це дасть вам всілякі проблеми з дотриманням PCI і надзвичайно небезпечно !! Незважаючи на те, що ви не зберігаєте інформацію про CC у своїй базі даних, якщо ви надсилаєте її на свій сервер, усі деталі будуть у ваших журналах, якщо хтось має доступ до ваших журналів, він має доступ до незашифрованої інформації про CC клієнта. Вам слід взагалі уникати надсилання цих даних на свій сервер. Якщо вам це дійсно потрібно, перегляньте шифрування на стороні клієнта ( developers.braintreepayments.com/javascript+ruby/sdk/client/… ). В іншому випадку скористайтеся прямими формами публікацій або сторонніми інструментами. Удачі!
Джей

Відповіді:


43

Ви можете використовувати 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 і тут корисне запитання щодо stackoverflow Що таке attr_accessor у Ruby?

Не змішуйте це з attr_accessible! Різниця між attr_accessor та attr_accessible


У мене є подальше запитання, після того, як я надіслав форму на контролері, як я можу "зняти" ці поля, пов'язані з CC, при виклику 'model.save', оскільки це може спричинити помилки?
zeratool

1
ви можете використовувати params.except(:card_number)у своєму контролері.
Trung Lê

48

Якщо я правильно зрозумів вашу відповідь, про те, що ви хочете зробити, пояснюється на офіційній вікі-сторінці тут: Створіть підроблений ввід, який НЕ читає атрибути . Ви можете використовувати поле, не пов’язане з жодним реальним стовпцем бази даних за пропозицією Едварда, однак вам не потрібно визначати атрибут у вашій моделі, якщо поле форми не має нічого спільного з моделлю.

Підводячи підсумок, фокус, який пояснюється на цій сторінці, полягає у визначенні користувацького вводу під назвою „FakeInput“ і використання його таким чином:

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

Не забудьте перезапустити ваш сервер rails після додавання / модифікації власного введення, як прокоментував Fitter Man.

ОНОВЛЕННЯ: Зверніть увагу, що офіційна сторінка 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

Приємно. Я ніколи цього не помічав.
Едвард

2
Можливо, вам доведеться перезапустити / перезавантажити веб-сервер, щоб це було підібрано.
Монтажер

З якихось причин це вже не працює. undefined method merge_wrapper_options for #<FakeInput:0x007fbe5e32beb8>
Трейн

@Trein Яку версію Rails / SimpleForm ви використовуєте?
baxang

@baxang Я використовую v3.0.2. Чи працює це на версіях rc? На жаль, я не можу використовувати версію rc для цього проекту (політики ...).
Трейн

41

Найкращий спосіб вирішити це - використовувати 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, оскільки вона не дозволяє використовувати різні типи входів. Це здається більш гнучким.

Зверніть увагу, хоча для того, щоб це працювало, мені довелося перейти :otherдо simple_fields_for. Ви можете передати будь-який рядок / символ , якщо немає моделі з таким самим іменем .

Тобто, на жаль, я не можу пройти :user, оскільки simple_form намагається створити екземпляр моделі користувача, і ми знову отримаємо те саме повідомлення про помилку ...


Найпростіші відповіді - найкращі. Працює для мене.
emptywalls

14

Крім того, якщо ви просто намагаєтеся щось додати і ввести це в 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 -%>

6

Я знайшов дуже просте (і дещо дивне) обхідне рішення.

Просто додайте input_htmlопцію з будь-якою valueклавішею всередині. Наприклад:

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

Перевірено просто_з версій: 3.2.1, 3.5.1

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.