Relazioni tra tabelle

prima tabella customers, seconda tabella invoices con customers_id che
fa chiaramente riferimento a customers.
nel model di costumers, has_many invoice nel model di invoices
belongs_to customer.
ho poi creato una view per customer, che mi visualizza solo alcuni campi
di customer. a fianco di ogni record di customer, con link_to o creato
dei collegamenti alle varie azioni crud, ma anche una azione che punta
al controller invoice. in pratica cliccando direttamente sul link
‘fattura’ vengo rediretto all’azione new invoice.
il problema sta qui. come faccio a fargli capire che questa nuova
fattura che sto creando è del customers da cui ho cliccato? infatti
cliccando su crea mi compare l’errore: il campo customer_id non può
essere vuoto.

sarebbe possibile tramite una select selezionare un cliente e fare in
modo che automaticamente compaiano anche tutti gli altri elementi del
record?

Prima domanda: i controller sono REST o sono quelli classici? Se sono
REST, hai mappato la risorse invoice come nested di customer?

Se invece stai utilizzando l’approccio non RESTful, quando fai il
link_to dovresti fare così:

link_to :controller => ‘invoice’, :action => ‘show(penso)’, :customer_id
=> @customer

Jamba J. ha scritto:

Giovanni I. wrote:

Prima domanda: i controller sono REST o sono quelli classici? Se sono
REST, hai mappato la risorse invoice come nested di customer?

Se invece stai utilizzando l’approccio non RESTful, quando fai il
link_to dovresti fare così:

link_to :controller => ‘invoice’, :action => ‘show(penso)’, :customer_id
=> @customer

Jamba J. ha scritto:

i controlli sono quelli classici. il link_to è proprio come lo hai
indicato tu, solo che al posto di show o scritto new perchè creo una
nuova fattura.
che vantaggio ho ad utilizzare controlli REST?

Forse è meglio che ci mostri sia le due azioni dei controller
coinvolte sia la view.

Il giorno 09/ott/07, alle ore 09:35, Jamba J. ha scritto:

Giovanni I. wrote:

Forse � meglio che ci mostri sia le due azioni dei controller
coinvolte sia la view.

Il giorno 09/ott/07, alle ore 09:35, Jamba J. ha scritto:

ok. nella pausa pranzo posto il codice.

il problema resta.
facendo una selct direttamente da mysql sulla tabella invoices, mi sono
accorto che il campo customer_id è NULL…

In che modo crei i nuovi invoice?

Il giorno 09/ott/07, alle ore 12:38, Jamba J. ha scritto:

c’è ancora molto codice scaffold. comunque il problema di prima l’ho
risolto.

class CustomerController < ApplicationController
def index
list
render :action => ‘list’
end

GETs should be safe (see

URIs, Addressability, and the use of HTTP GET and POST)
verify :method => :post, :only => [ :destroy, :create, :update ],
:redirect_to => { :action => :list }

def list
@customer_pages, @customers = paginate :customers, :per_page => 10,
:order_by => “Surname”
end

def show
@customer = Customer.find(params[:id])
end

def new
@customer = Customer.new
end

def create
@customer = Customer.new(params[:customer])
if @customer.save
flash[:notice] = ‘Customer was successfully created.’
redirect_to :action => ‘list’
else
render :action => ‘new’
end
end

def edit
@customer = Customer.find(params[:id])
end

def update
@customer = Customer.find(params[:id])
if @customer.update_attributes(params[:customer])
flash[:notice] = ‘Customer was successfully updated.’
redirect_to :action => ‘show’, :id => @customer
else
render :action => ‘edit’
end
end

def destroy
Customer.find(params[:id]).destroy
redirect_to :action => ‘list’
end
end

class InvoiceController < ApplicationController
def index
list
render :action => ‘list’
end

GETs should be safe (see

URIs, Addressability, and the use of HTTP GET and POST)
verify :method => :post, :only => [ :destroy, :create, :update ],
:redirect_to => { :action => :list }

def list
@invoice_pages, @invoices = paginate :invoices, :per_page => 10
end

def show
@invoice = Invoice.find(params[:id])
end

def new
@invoice = Invoice.new
end

def create
@invoice = Invoice.new(params[:invoice])
if @invoice.save
flash[:notice] = ‘Invoice was successfully created.’
redirect_to :action => ‘list’
else
render :action => ‘new’
end
end

def edit
@invoice = Invoice.find(params[:id])
end

def update
@invoice = Invoice.find(params[:id])
if @invoice.update_attributes(params[:invoice])
flash[:notice] = ‘Invoice was successfully updated.’
redirect_to :action => ‘show’, :id => @invoice
else
render :action => ‘edit’
end
end

def destroy
Invoice.find(params[:id]).destroy
redirect_to :action => ‘list’
end
end

questa è la view di customers

Anagrafica Clienti

<% odd_or_even = 0 for customer in @customers odd_or_even = 1 - odd_or_even %> >
  <td width= "60">
    <span class ="content h1"><%= (customer.surname) %></span><br />
  </td>

  <td width= "60">
    <span class ="content h1"><%= (customer.name) %></span><br />
  </td>


  <td class="ListActions">
    <%= link_to 'Fattura', :controller => 'invoice', :action => 

‘new’, :customer_id => @custmer %>
<%= link_to ‘Mostra’, :action => ‘show’, :id => customer %>
<%= link_to ‘Modifica’, :action => ‘edit’, :id => customer %>
<%= link_to ‘Cancella’, {:action => ‘destroy’, :id => customer
},
:confirm => “Sei sicuro?” %>


<% end %>

<%= if @customer_pages.current.previous
link_to(“Pagina prec.”,{ :page =>
@customer_pages.current.previous})
end
%>

<%= if @customer_pages.current.next
    link_to("Pagina succ.",{ :page => @customer_pages.current.next})
    end
%>
<br />
<%= link_to 'Nuovo cliente', :action => 'new' %>

questa è invece quella di invoice

Elenco fatture

<% odd_or_even = 0 for invoice in @invoices odd_or_even = 1 - odd_or_even %> >
  <td width= "60">
    <span class ="content h1"><%= (invoice.invoices_number) 

%>

  <td width= "60">
    <span class ="content h1"><%= (invoice.items) %></span><br />
  </td>

  <td width= "60">
    <span class ="content h1"><%= (invoice.date) %></span><br />
  </td>

  <td width= "60">
    <span class ="content h1"><%= (invoice.customer_id) %></span><br 

/>

  <td class="ListActions">
    <%= link_to 'Mostra', :action => 'show', :id => invoice %>
    <%= link_to 'Modifica', :action => 'edit', :id => invoice %>
    <%= link_to 'Cancella', {:action => 'destroy', :id => invoice },
                :confirm => "Sei sicuro?" %>
  </td>
</tr>
<% end %>
</table>
<%= if @invoice_pages.current.previous
    link_to("Pagina prec.",{ :page => 

@invoice_pages.current.previous})
end
%>

<%= if @invoice_pages.current.next
    link_to("Pagina succ.",{ :page => @invoice_pages.current.next})
    end
%>
<br />
<%= link_to 'Nuovo cliente', :action => 'new' %>

Giovanni I. wrote:

In che modo crei i nuovi invoice?

le tue domande mi fanno sempre venire qualche dubbio.

questo è il codice scaffold

def new
@invoice = Invoice.new
end

def create
@invoice = Invoice.new(params[:invoice])
if @invoice.save
flash[:notice] = ‘La fattura è stata creata.’
redirect_to :action => ‘list’
else
render :action => ‘new’
end
end

nella view di customer punto a new, ma create sembra più completa, ma se
in customer inserisco l’azione create, non mi punta alla view new ma
alla list

molto rilento ma sto andando avanti.
ho cambiato un pò le cose. adesso ho messo una select su new invoice.
non è il massimo della linearità , perchè clicco new invoice da un
customers, e poi su new invoice posso ancora cambiare il customer, ma è
l’unico modo che funziona.
infatti se provo con la select funziona e alla fattura viene
effettivamente abbinato il customer scelto, se inseriso un text_field,
no, il campo customer_id rimane NULL.

suggerimenti?

Rispondo di fretta cmq ad occhio dovresti avere nella view customer

link_to :controller => ‘invoice’, :action => ‘new’, :customer_id =>
@customer,

poi cambiare il metodo new di InvoiceController in questo modo

def new
@invoice = Invoice.new(:customer => Customer.find(params
[:customer_id]))
end

e modificare la view mettendo un hidden_field che riporti l’id del
customer.

Infine modifica il metodo create facendo un altro find per trovare il
customer in modo da poter creare l’invoice correttamente. Non è il
metodo più pulito (e non è il metodo che userei io) ma dovrebbe
funzionare :slight_smile:

Il giorno 09/ott/07, alle ore 18:30, Jamba J. ha scritto: