Query personalizzata

Sicuramente sono ancora troppo fresco in rails, ma mi sembra di aver
capito
che la controparte dell’estrema semplicità nell’uso di ActiveRecord sia
la
difficolta’ nel personalizzare le query.

Ad esempio ipotiziamo di dover gestire una videoteca e quindi tutti i
film appartenenti. Voglio creare al volo un PDF con determinati
paramentri, tipo
anno di uscita, regista, attore… e tutte ste cose qua. Per ora ho
risolto il problema della query personalizzata in questo modo:

if params[:catalogue][:kind] != nil && params[:catalogue][:kind] != “”
kinds = params[:catalogue][:kind].each { |kind|
@cond << " OR " if @cond!=""
@cond << “kind_id = #{kind}”
}
@to_clean = false
end

if params[:catalogue][:shortCast] != “”
@cond << " AND " if @cond!=""
@cond << “shortCast LIKE ‘%#{params[:catalogue][:shortCast]}%’”
@to_clean = false
end

if params[:catalogue][:year] != “”
@cond << " AND " if @cond!=""
@cond << “year LIKE #{params[:catalogue][:year]}”
@to_clean = false
end

E quindi poi potevo fare così:

@filmP = Film.find(:all, :conditions => @cond)

Ora però mi si è posto l’ennesimo problema.
Di ogni genere devi prendere al max 8 film.

Secondo voi dovrei far uso della clausola HAVING combinata con il GROUP
BY ?!!?

Ora però mi si è posto l’ennesimo problema.
Di ogni genere devi prendere al max 8 film.

Secondo voi dovrei far uso della clausola HAVING combinata con il GROUP
BY ?!!?

Ciao Ale,

Probabilmente ho capito male… ma non puoi utilizzare :limit => 8

Andrea

Andrea R. wrote:

Ora però mi si è posto l’ennesimo problema.
Di ogni genere devi prendere al max 8 film.

Secondo voi dovrei far uso della clausola HAVING combinata con il GROUP
BY ?!!?

Ciao Ale,

Probabilmente ho capito male… ma non puoi utilizzare :limit => 8

Andrea

Ciao Andrea,
si non è quello che dicevo io… A me servono più di 8 records, ma
vorrei ad esempio 8 films della categoria Animazione, poi 8 films della
categoria Triller, poi 8 della cat Animazine, e così via… quindi alla
fine potrei anche avere 64 films, ma non ne voglio più di 8 per genere.
Tutto ciò senza esser costretto di fare più queries…

On Jun 26, 2008, at 3:05 PM, Ale Z. wrote:

Ciao Andrea,
si non è quello che dicevo io… A me servono più di 8 records, ma
vorrei ad esempio 8 films della categoria Animazione, poi 8 films
della
categoria Triller, poi 8 della cat Animazine, e così via… quindi
alla
fine potrei anche avere 64 films, ma non ne voglio più di 8 per
genere.
Tutto ciò senza esser costretto di fare più queries…

Mi baso piu’ sull’esperienza che sui (pochi) ricordi di algebra
relazionale, e
quindi potrei sbagliarmi, ma non mi sembra che sia possibile fare
tutto con una sola query.
Perche’ non vuoi fare piu’ query? La soluzione sarebbe piu’ che banale.

S.

class Movie < ActiveRecord::Base
has_and_belongs_to_many :categories
end

class Category < ActiveRecord::Base
has_and_belongs_to_many :movies
has_many :most_recent_movies,
:class_name => ‘Movie’, :limit => 10,
:order => ‘created_at DESC’

def self.search(names)
find(:all, :conditions => [‘name IN(?)’, names],
:include => :most_recent_movies)
end
end

Category.search([‘Action’, ‘Fantasy’])

Ritorna le categorie, con già caricati gli ultimi dieci film, il che
significa che il tutto viene risolto in una sola query. Guarda il file
di log :wink:

Luca

blog: www.lucaguidi.com
Pro-Netics: www.pro-netics.com
Sourcesense - making sense of Open Source: www.sourcesense.com

Ale Z. wrote:

Andrea R. wrote:

Ora però mi si è posto l’ennesimo problema.
Di ogni genere devi prendere al max 8 film.

Secondo voi dovrei far uso della clausola HAVING combinata con il GROUP
BY ?!!?

Ciao Ale,

Probabilmente ho capito male… ma non puoi utilizzare :limit => 8

Andrea

Ciao Andrea,
si non è quello che dicevo io… A me servono più di 8 records, ma
vorrei ad esempio 8 films della categoria Animazione, poi 8 films della
categoria Triller, poi 8 della cat Animazine, e così via… quindi alla
fine potrei anche avere 64 films, ma non ne voglio più di 8 per genere.
Tutto ciò senza esser costretto di fare più queries…

Comprendo…

Allora temo che ti servano almeno due query anidate… una per i gruppi
ed una per i limiti.

Andrea

On Jun 26, 2008, at 6:44 PM, Luca G. wrote:

def self.search(names)
di log :wink:
A me sembra un po’ strano… ci fai vedere questa query?

S.

Stefano C. wrote:

On Jun 26, 2008, at 6:44 PM, Luca G. wrote:

def self.search(names)
di log :wink:
A me sembra un po’ strano… ci fai vedere questa query?

S.

Dici a me!?!?

Stefano C. wrote:

A me sembra un po’ strano… ci fai vedere questa query?

Per la fretta ho sbagliato due cose:

  1. Nella classe Movie anche la seconda macro è habtm, non hm
  2. Non mi sono accorto che l’eager loading non funziona bene, cioè
    esegue due query, una per le categorie, l’altra per caricare tutti i
    relativi movies, ignorando, tra l’altro, il limit imposto da
    most_recent_movies.

SELECT * FROM “categories” WHERE (name in (‘Action’,‘Fantasy’))

SELECT “movies”.*, t0.category_id as _parent_record_id FROM “movies”
INNER JOIN “categories_movies” as t0 ON “movies”.id = t0.movie_id WHERE
(t0.category_id IN (1,2))

Luca

blog: www.lucaguidi.com
Pro-Netics: www.pro-netics.com
Sourcesense - making sense of Open Source: www.sourcesense.com