[RAILS] contare elementi di un campo


#1

Salve. sto portando avanti una piccola applicazione in rails - un
piccolo gestionale per le fatture del mio ufficio -. In una view, voglio
realizzare una tabella dove vengono elencati i clienti e nelle colonne a
fianco il numero delle fatture associate per ogni cliente.
riesco a fare tutto tranne che il numero delle fatture associato ad ogni
cliente. riesco a viasulizzare solo il numero totale dei record…
lo spezzone di codice è questo:

<% @customers.each do |customer| %> <%= customer.id %> <%= link_to customer.name, edit_customer_path(customer) %> <%= link_to Invoice.count("number"), :controller => "invoices", :action =>"index" %> <%= link_to Document.count("number"), :controller => "documents", :action => "index"%> <% end %>

#2

Il 21 aprile 2009 0.10, jamba jamba removed_email_address@domain.invalid ha scritto:

Salve. sto portando avanti una piccola applicazione in rails - un
piccolo gestionale per le fatture del mio ufficio -. In una view, voglio
realizzare una tabella dove vengono elencati i clienti e nelle colonne a
fianco il numero delle fatture associate per ogni cliente.

il metodo count accetta molti dei parametri accettati da find, e in
particolare :conditions.

Document.count :conditions => [“campochesiriferiscealcliente = ?”,
customer.id]

d’altronde, però, probabilmente c’è un’associazione, nel db, tra il
cliente e le fatture, per cui dovresti poter scrivere, più
comodamente:

customer.documents.count

pietro


#3

jamba jamba wrote:

Salve. sto portando avanti una piccola applicazione in rails - un
piccolo gestionale per le fatture del mio ufficio -. In una view, voglio
realizzare una tabella dove vengono elencati i clienti e nelle colonne a
fianco il numero delle fatture associate per ogni cliente.
riesco a fare tutto tranne che il numero delle fatture associato ad ogni
cliente. riesco a viasulizzare solo il numero totale dei record…
lo spezzone di codice è questo:

Io avevo un problema analogo: contare quante volte una persona era stata
chiamata e altre statistiche.
ho fatto una cosa del genere (un estratto):

<% for user in @user %>
<% @contatti.each do |tel| %>
<% if tel.nonrisponde == true and tel.chiamatoda == user.login %>
<% nonrisposteoggi +=1 %>
<% else %>
<% end %>
<% if tel.nuovo == true and tel.chiamatoda == user.login %>
<% nuovioggi +=1 %>
<% else %>
<% end %>

con “user” che contiene gli operatori che chiamano e “@contatti” la
lista di persone chiamate con gli opportuni campi valorizzati. Sì, è un
accrocchio del cavolo, ma era la cosa più veloce da fare e non c’era
molto tempo ':slight_smile:


#4

Sandro P. wrote:

mmh… potresti fare due named_scope ‘not_answered_today’ e ‘new_today’
all’interno del model ‘Contact’ e poi ciclare su user:

<% @user.each do |user|

nonrisposteoggi = user.contacts.not_answered_today.count
nuovioggi = user.contacts.new_today.count

%>

<% end %>

Uhm… forse era meglio chiedere un po’ di aiuto qui, invece di
impazzire: quel “count” proprio non mi è mai passato per la mente, per
non parlare dei “named_scope” :slight_smile:

Approfondirò per il prossimo anno.


#5

Pietro G. wrote:

Il 21 aprile 2009 0.10, jamba jamba removed_email_address@domain.invalid ha scritto:

Salve. sto portando avanti una piccola applicazione in rails - un
piccolo gestionale per le fatture del mio ufficio -. In una view, voglio
realizzare una tabella dove vengono elencati i clienti e nelle colonne a
fianco il numero delle fatture associate per ogni cliente.

il metodo count accetta molti dei parametri accettati da find, e in
particolare :conditions.

Document.count :conditions => [“campochesiriferiscealcliente = ?”,
customer.id]

d’altronde, per�, probabilmente c’� un’associazione, nel db, tra il
cliente e le fatture, per cui dovresti poter scrivere, pi�
comodamente:

customer.documents.count

pietro

funziona! ho scelto customer.documents.count, mi sembra meglio…
ora ho un altro problemino.
come azione associata a quel link_to ho un “index” che mi fa vedere
tutte i record. vorrei fare in modo che mi facci avedere tutti i record
associati a quel cliente.
dovrei quindi definire un metodo index "particolare nel controller, e
poi una view “particolare”. Il problema è però come faccio ad
individuare a quale cliente si riferisce il mio click?


#6

mmh… potresti fare due named_scope ‘not_answered_today’ e ‘new_today’
all’interno del model ‘Contact’ e poi ciclare su user:

<% @user.each do |user|

nonrisposteoggi = user.contacts.not_answered_today.count
nuovioggi = user.contacts.new_today.count

%>

<% end %>

2009/4/21 Daneel O. removed_email_address@domain.invalid


#7

jamba jamba wrote:

funziona! ho scelto customer.documents.count, mi sembra meglio…
ora ho un altro problemino.
come azione associata a quel link_to ho un “index” che mi fa vedere
tutte i record. vorrei fare in modo che mi facci avedere tutti i record
associati a quel cliente.
dovrei quindi definire un metodo index "particolare nel controller, e
poi una view “particolare”. Il problema è però come faccio ad
individuare a quale cliente si riferisce il mio click?

Vediamo se mi ricordo… “link_to” deve puntare ad un metodo (si
chiamano così i “def” dentro “controller”, giusto? sì, lo so, sono preso
male…) con “:action => faqualcosa” e a questo passerai la variabile
(“id => idcliente” … o anche “:params => idcliente”? non ricordo), che
sarà l’id del cliente o qualcosa del genere.

Nel metodo ci sarà una funzione di ricerca che cercherà le fatture del
cliente e la vista associata le mostrerà .

Ho la memoria che funziona, o è meglio che mi metta a ripassare anch’io?


#8

jamba jamba wrote:

Daneel O. wrote:

Vediamo se mi ricordo… “link_to” deve puntare ad un metodo (si
chiamano così i “def” dentro “controller”, giusto? sì, lo so, sono preso
male…) con “:action => faqualcosa” e a questo passerai la variabile
(“id => idcliente” … o anche “:params => idcliente”? non ricordo), che
sarà l’id del cliente o qualcosa del genere.

Nel metodo ci sarà una funzione di ricerca che cercherà le fatture del
cliente e la vista associata le mostrerà .

Ho la memoria che funziona, o è meglio che mi metta a ripassare anch’io?

il procedimento è quello esatto, il problema è però far capire a rails,
che idcliente, è quello da cui ho cliccato…

Se hai la lista dei clienti, potrebbe essere una cosa del genere:
<% @clienti.each do |clienti| %>

<%= clienti.id %> <%= link_to clienti.nome, action => "list", :id => dati.id %> ...

supponendo che la tabella clienti abbia la colonna nome; sul def list (o
quello che sarà ) ci dovrà essere una ricerca sulla tabella delle fatture
con quell’id e la view dovrà generare la tabella.
Una cosa del genere, insomma:

def list
@fatture = Fatture.find(params[:id])
end

P.s.: occhio alle pluralizzazioni: qui ho scritto in italiano per pura
pigrizia :slight_smile:


#9

Daneel O. wrote:

Vediamo se mi ricordo… “link_to” deve puntare ad un metodo (si
chiamano così i “def” dentro “controller”, giusto? sì, lo so, sono preso
male…) con “:action => faqualcosa” e a questo passerai la variabile
(“id => idcliente” … o anche “:params => idcliente”? non ricordo), che
sarà l’id del cliente o qualcosa del genere.

Nel metodo ci sarà una funzione di ricerca che cercherà le fatture del
cliente e la vista associata le mostrerà .

Ho la memoria che funziona, o è meglio che mi metta a ripassare anch’io?

il procedimento è quello esatto, il problema è però far capire a rails,
che idcliente, è quello da cui ho cliccato…


#10

questa è la view:
<% @customers.each do |customer| %>


<%= customer.id %>
<%= link_to customer.name, edit_customer_path(customer)
%>
<%= link_to customer.invoices.count,
:controller => “invoices”, :action =>“list”, :id => customer.invoices.id
%>
<%= link_to customer.documents.count,
:controller => “documents”, :action => “index”%>

<% end %>

questo è uno spezzone del controller:

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

e questo è l’errore che ottengo:
No action responded to list. Actions: create, destroy, edit, index, new,
public_invoices, search, show translation missing: it-IT, support,
array, sentence_connector update


#11

jamba jamba wrote:

questa è la view:
<% @customers.each do |customer| %>


<%= customer.id %>
<%= link_to customer.name, edit_customer_path(customer)
%>
<%= link_to customer.invoices.count,
:controller => “invoices”, :action =>“list”, :id => customer.invoices.id
%>
<%= link_to customer.documents.count,
:controller => “documents”, :action => “index”%>

<% end %>

questo è uno spezzone del controller:

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

e questo è l’errore che ottengo:
No action responded to list. Actions: create, destroy, edit, index, new,
public_invoices, search, show translation missing: it-IT, support,
array, sentence_connector update

Domanda banale: hai salvato?

Totnando al quesito originale: se la risorsa invoice è sempre collegata
all’utente di riferimento esiste un sistema molto più elegante e
funzionale, quello di nidificare la risorsa invoice sotto customer ed
avresti potuto evitare un metodo al tuo povero controller, il tuo link
sarebbe stato:

<%= link_to @customer.invoices.count, customer_invoices_url %>

Farlo è semplice, devi modificare le routes nidificando le invoices
sotto il proprio customer:

map.resources :customers do |customer|
customer.resources :invoices
end

all’interno del controller invoices devi aggiungere:
before_filter :load_parents

def load_parents
@customer = Customer.find(params[:customer_id]) if
params[:customer_id]
end

Poi devi convertire tutti i richiami alle routes di invoices, sia nel
controller dove hai aggiunto quelle righe in alto che nelle views, per
esempio:

dove nel controller c’era
redirect_to(@invoice)
diventa
redirect_to([@customer,@invoice])

oppure nelle views:
la vecchia route invoices_url diventa customer_invoices_url
insomma devi aggiungere customer (singolare) davanti la route e dove
viene passato l’oggetto @invoice deve diventare un array
[@customer,@invoice]

Per ulteriori chiarimenti puoi leggere questo tutorial, forse è più
chiaro:


#12

jamba jamba wrote:

questa è la view:
<% @customers.each do |customer| %>


<%= customer.id %>
<%= link_to customer.name, edit_customer_path(customer)
%>
<%= link_to customer.invoices.count,
:controller => “invoices”, :action =>“list”, :id => customer.invoices.id
%>
<%= link_to customer.documents.count,
:controller => “documents”, :action => “index”%>

<% end %>

questo è uno spezzone del controller:

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

e questo è l’errore che ottengo:
No action responded to list. Actions: create, destroy, edit, index, new,
public_invoices, search, show translation missing: it-IT, support,
array, sentence_connector update

Boh… mai visto quell’errore…
Il codice soprastante mi sembra corretto… se non ci sono altre cose
strane, non saprei che dirti. Che dice la gente più esperta?


#13

Daneel O. wrote:

Boh… mai visto quell’errore…
Il codice soprastante mi sembra corretto… se non ci sono altre cose
strane, non saprei che dirti. Che dice la gente più esperta?

Me ne guardo bene dal definirmi un esperto ma a questo posso rispondere
anche io, l’errore mi sembra molto semplice, non esiste il metodo! Per
quello chiedevo se aveva salvato il controller dopo la modifica, non
vedo altre cause


#14

Me ne guardo bene dal definirmi un esperto ma a questo posso rispondere
anche io, l’errore mi sembra molto semplice, non esiste il metodo! Per
quello chiedevo se aveva salvato il controller dopo la modifica, non
vedo altre cause

è la prima cosa che ho pensato, ma tutti i file sono stati salvati. ho
provato anche a riavviare il server, ma nulla…

tutto il codice è su github
git://github.com/jamba/geometrix.git

se ti va di dargli un occhio…


#15

jamba jamba wrote:

Me ne guardo bene dal definirmi un esperto ma a questo posso rispondere
anche io, l’errore mi sembra molto semplice, non esiste il metodo! Per
quello chiedevo se aveva salvato il controller dopo la modifica, non
vedo altre cause

è la prima cosa che ho pensato, ma tutti i file sono stati salvati. ho
provato anche a riavviare il server, ma nulla…

tutto il codice è su github
git://github.com/jamba/geometrix.git

se ti va di dargli un occhio…

Non è un discorso di voglia (smanetterei dalla mattina alla sera) ma più
che altro di tempo…
hai controllato le routes? Verifica che ci sia la generica dove
specifichi controller ed action, senza il tipo formato perchè mi sembra
non l’hai specificato.
Oppure prova a mapparti una route tipo:

#config/routes.rb
map.invoices_list ‘invoices/:id/list’, :controller => ‘invoices’,
:action => ‘list’

#nella view
<%= link_to @customer.invoices.count, invoices_list_url(@customer) %>