2013-02-11 10 views
5

Fondamentalmente, ho definito una proprietà sul mio modello che restituisce true o false a seconda dei valori in un'altra tabella.Come restituire i risultati filtrati sul conteggio delle relazioni in una vista in RAILS?

Quello che voglio è avere la mia azione Index nel controller per restituire solo quei risultati che soddisfano questa condizione.

ho provato questo:

#What I've tried on my Controller: 
def index 
    @projects = Project.where(:is_available?) 
end 

#What I've on my Controller: 
def index 
    @projects = Project.all 
end 

#What I've on my Model: 
def is_available? 
    workers.count<2 ? true : false 
end 

Grazie.

risposta

10

Perché il tuo codice non funziona?

Project.where(:is_available?) 

Qui nel metodo in cui, è necessario passare un hash di argomenti o una serie di condizioni (SQL). Quello che stai cercando di fare qui è selezionare tutti i progetti in cui il metodo è disponibile? ritorna vero Il problema è che il metodo is_available? è un metodo Ruby (definito nel modello). Poiché si tratta di una funzione Ruby, non è possibile chiamarla all'interno di SQL. Il metodo where prevede le condizioni SQL, non il codice ruby.

(Grazie a @benzado per il commento)


per risolvere il problema:

Questo è quello che stai cercando, calcolata solo a livello db:

Project.joins(:workers) 
     .select('projects.*') 
     .group('projects.id') 
     .having('COUNT(workers.*) > 2') 

Questo dovrebbe restituire tutti i progetti con almeno 2 dipendenti associati.


Come migliorare questo?

si può fare un ambito di questa query, per utilizzarlo ovunque facilmente:

#in your model 
class Project < ActiveRecord::Base 
    scope :having_more_than_x_workers, lambda do |workers_count| 
    joins(:workers).select('projects.*').group('projects.id').having("COUNT(workers.*) > #{workers_count || 0}") 
    end 

end 

di usarlo, nel controller, ad esempio:

#in your controller 
def index 
    @projects = Project.having_more_than_x_workers(2) 
end 
+0

Questo è il modo giusto per farlo, ma non si spiega * perché * @ il codice di met.lord non funzionava. Sentiti libero di copiare qualsiasi cosa dalla mia risposta alla tua per migliorare questo. – benzado

3

I metodi di query Rails (come where) funziona creando una query di database; in altre parole, non è possibile utilizzare un attributo in where a meno che non esista effettivamente sul modello di dati. Altrimenti, il database non lo sa e non può eseguire il filtraggio per te.

Nel tuo caso, dovresti definire un metodo sulla classe Project che esegue "è disponibile?" query, in modo da poter utilizzare il metodo al posto di where. Si può fare in questo modo:

class Project < ActiveRecord::Base 
    def self.available_projects 
    where('workers_count > 2') 
    end 
end 

Vedi MrYoshiji's answer per le specifiche su come scrivere la query o il modo di definirlo come un ambito di nome.

Problemi correlati