Вставьте две строки в одно действие создания в контроллере - PullRequest
0 голосов
/ 15 декабря 2009

У меня есть форма, которая используется для записи транзакции. Жидкость перемещается из одного резервуара в другой. Моя форма принимает из бака и в бак и количество переданных галлонов. Я хотел бы, чтобы это было введено в базу данных в виде двух строк. Первым будет идентификатор от Tank и отрицательное число, а второй строкой будет идентификатор Tank и положительное число.

Пример: Перенос 36 галлонов из танка 1 в танк 2

    id   | tank_id | tran_amount
   ------------------------------
     1   |    1    |     -36
     2   |    2    |      36

Это то, чего я бы легко достиг, написав код SQL на PHP, но я в недоумении в Rails. Как я могу сделать это из одной формы?

Ответы [ 3 ]

1 голос
/ 15 декабря 2009

Его модель верна. Таблица транзакций в стиле учета содержит только идентификатор счета и сумму транзакции. Вы должны использовать сохранение транзакции, чтобы обеспечить правильное сохранение обеих записей или сбой обеих записей.

Для этого я бы выбрал простую версию тега формы.

<% form_tag url => { :controller => "controller", :action => "action" }, :method => "post" do %>
     <p>From Account: <%= text_field_tag :from_account %></p>
     <p>To Account: <%= text_field_tag :to_account %></p>
     <p>Amount: <%= text_field_tag :amount %></p>
     <p><%= submit_tag "Transfer" %>

<% end %>

В контроллере я бы затем создал обе модели переноса и сохранил их вместе как транзакцию.

1 голос
/ 15 декабря 2009

Я бы смоделировал это по-другому. Надеюсь, это даст вам некоторые идеи ... Я не уверен, что это будет работать как есть ...

class TankTransfer < AR:B
    has_one :from_transfer
    has_one :to_transfer

    attr_accessible :from_tank
    attr_accessible :to_tank
    attr_accessible :amount_to_transfer

    before_create :create_transfers
protected
    def create_transfers
      self.to_transfer.build(:tank => self.to_tank, :amount => self.amount_to_transfer)
      self.from_transfer.build(:tank=> self.from_tank, :amount => -self.amount_to_transfer)
    end
end

class Transfer < AR:B
    belongs_to :tank
end

class Tank < AR:B
    has_many :transfers
end

Тогда ваша форма будет выглядеть (если вы используете formtastic):

<% semantic_form_for @tank_transfer do |form| %>
  <% form.inputs :name => "Tank transfer" do %>
    <%= form.input :from_tank %>
    <%= form.input :to_tank %>
    <%= form.input :amount_to_transfer %>
  <% end %>
  <% form.buttons do %>
      <%= form.commit_button %>
  <% end %>
<% end %>

Ваш контроллер будет очень простым контроллером, как вы видите во всех примерах.

1 голос
/ 15 декабря 2009

Что-то здесь не хватает в вашей модели базы данных, разве вы не хотите, чтобы что-то связало передачу? Я бы сделал:

id | from_tank_id | to_tank_id | transfer_amount

Если вы застряли в существующей модели, которая предположительно находится в модели с именем Transfer, ничто не мешает вам создать два в контроллере, просто поместите их в транзакцию.

#in TransferController.create
amount = params[:amount].to_i
Transfer.transaction do
  Transfer.create(:tank_id => params[:from_tank_id], :tran_amount => -amount)
  Transfer.create(:tank_id => params[:to_tank_id], :tran_amount => amount)
end
...