Mehrer einträge in die datenba nk schreiben

Hallo,
ich möcht mit einem formular mehrer einträge in die datenbank schreiben.

Ich habe beliebig viele kosten (CostItem). Diese kosten werden auf
beliebig
viele user
aufgeteilt (PartialAmount).

‘CostItem’ und ‘PartialAmount’ stehen in einer 1:N Beziehung.
‘User’ und ‘PartialAmount’ stehen in einer 1:N Beziehung.

folgendes habe ich bei mir im view stehen: (vereinfacht :wink:

<%- form_for :partial_amount, :url => { :controller => ‘cost’, :action
=>
‘apportionment_save’ }, :html => { :id => ‘monthly_cost’ } do |f|
<%- @cost_item.each do |item| %>
<%= f.hidden_field :cost_item_id, :value => item.id %>
<%- @user.each do |user| %>
<%- fields_for :partial_amount, @partial_amount do
|partial_amount_form| %>
<%= user.login %>
<%= partial_amount_form.text_field :amount %>
%p.action
= submit_tag ‘Save changes’

es soll also für jeden ‘cost_item’ mehrere ‘partial_amount’ in die
datenbank
geschrieben werden.

Das ganze funktioniert, aber in der datenbank taucht nur ein eintrag
auf.

Ich habe so etwas ähnliches schon einmal realisiert (siehe
#73 Complex Forms Part 1 - RailsCasts ) aber das waren zwei models. hier
habe
ich nur ein modell.

danke schonmal für die Hilfe.

grüße kalle

Kalle,

Ryan B. hat sich in den aktuellen Railscasts Episoden damit
beschäftigt.
die Complex Form Serie ist allgemein sehr schön:

http://railscasts.com/episodes/74

mfg

Am 19.10.07 schrieb kalle saas [email protected]:

hey, ja die railscast sind schick, habe die auch schon in mein projekt
eingearbeitet klappt auch
prima, aber in diesem fall mit nur einem Modell im Form bekomme ich das
mit
den vitrual attributes nicht hin.
da wäre z.B. die frage, wenn ich nur ein modell hab kann ich dann mit
form_for folgendes machen:

-> das funzt: fields_for “cost[cost_items_attributes][]”, cost do
|cost_items_form|

das auch?
-> form_for “cost[cost_items_attributes][]”, cost , :url => {
:controller
=> ‘cost’, :action => ‘create’ }, :html => { :id => ‘monthly_cost’ } do
|f|

cost.rb modell
def cost_items_attributes=(cost_items_attributes)
cost_items_attributes.each do |attributes|
cost_items.build(attributes)
end
end

greets kalle

im prinzip musst du doch nur im controller über dein array iterieren und
mehrere saves machen, oder versteh ich hier was falsch?

gruß
manuel

Hey,
wie ich mir das schon ein bisschen gedacht habe war mein ansatz etwas
kompliziert…
mit dem folgenden habe ich es schonmal geschafft einen array an input an
den
server zu übertragen. Aber nicht alle daten in die datenbank zu
übertragen.

ich habe dazu einfach aus:
<%= partial_amount_form.text_field :amount %>
das gemacht:
<%= f.text_field :amount, :size => 10, :name =>
“partial_amount[amount][]”
%>

-> partial_amount[amount][] dadurch wird der array erzeugt.

der view:

  • form_for :partial_amount, :url => { :controller => ‘cost’, :action =>
    ‘apportionment_save’ }, :html => { :id => ‘monthly_cost’ } do |f|
    • @cost_item.each do |item|
      = f.hidden_field :cost_item_id, :value => item.id
      = text_field_tag ‘amount’, item.amount , :size => 10,
      :readonly =>
      ‘readonly’
      - @user.each_with_index do |user, i|
      = user.login
      = f.hidden_field :user_id, :value => user.id, :name =>
      “partial_amount[user_id][]”
      = f.text_field :amount, :size => 10, :name =>
      “partial_amount[amount][]”
      %p.action
      = submit_tag ‘Save changes’

das log:
Parameters: {“commit”=>“Save changes”,
“partial_amount”=>{“amount”=>[“21”,
“21”, “123321”, “21”, “21”, “21”], “user_id”=>[“15”, “17”, “15”, “17”,
“15”,
“17”], “cost_item_id”=>“100”}, “action”=>“apportionment_s
e”, “amount”=>“12”, “controller”=>“cost”}

mysql:
←[4;36;1mSQL (0.000000)←[0m ←[0;1mINSERT INTO partial_amounts
(amount,
user_id, cost_item_id) VALUES(1, 1, 100)←[0m

die VALUES(1, 1, 100) stimmn nicht.

controller:

def apportionment_save
@partial_amount = PartialAmount.new(params[:partial_amount])
if request.post?
if @partial_amount.save
flash[:notice] = “Visite erfolgreich angelegt”
redirect_to :controller => “cost”, :action => “list”
end
end
end

wie kann ich jezt den array komplett übertragen?

hat jemand ein tipp für mich?

greets kalle

Hey,
ja so hab ich das jetzt gelöst, mit einer Iteration über den Array.
Ich hatte nur gedacht das es eine elegantere Losung gibt etwa mit der
Nutzung von virtuellen Attributen. Damit man die ganze Iteration nicht
im
Controller machen muss. Ich könnte mir auch vorstellen das das geht,
kenn
mich da aber nicht so gut aus…

meine Lösung:
Parameters:
“partial_amount”=>{
“amount”=>[“11”, “12”, “13”, “21”, “22”, “23”, “31”, “32”, “33”],
“user_id”=>[“15”, “17”, “18”, “15”, “17”, “18”, “15”, “17”, “18”],
“cost_item_id”=>[“100”, “101”, “102”]}

Erklärung:
zu jedem cost_item (hier 3 ) werden beliebig viele user (hier 3) mit
ihren
beträgen ( amount) in die datenbank geschrieben

ich baue quasi im Controller ein partial_amount Objekt für jeden
cost_item_id / user Eintrag nach und speichere ihn.

def apportionment_save
memory = 0
params[:partial_amount][:cost_item_id].each_with_index do |item,
index|
@flat.users.each_with_index do |user_id, twindex|
@partial_amount = PartialAmount.new
@partial_amount.cost_item_id =
params[:partial_amount][:cost_item_id][index]
@partial_amount.user_id =
params[:partial_amount][:user_id][memory]
@partial_amount.amount =
params[:partial_amount][:amount][memory]
memory += 1
@partial_amount.save
end
end
end

für ne idee einer eleganteren lösung bin ich auf jeden fall dankbar
(lernen!)

grüße kalle