Parte del motivo per cui amo Rails è che io odio SQL - Penso che sia più simile a un linguaggio assembly che deve essere manipolato con gli strumenti di livello superiore, come ActiveRecord. Mi sembra di aver raggiunto i limiti di questo approccio, tuttavia, e sono fuori dalla mia profondità con l'SQL.Richiesta di binari complessi - unioni? sub-selezionare? posso ancora usare named_scope?
Ho un modello complesso con un sacco di sotto-record. Ho anche un set 30_40 named_scope che implementa la logica di business dal client. Questi ambiti vengono concatenati insieme in modo condizionale, motivo per cui dispongo degli ambiti joins_
in modo che i join non vengano danneggiati.
Ne ho un paio che non funzionano correttamente, o almeno non come il cliente vuole che funzionino. Ecco un'idea approssimativa della struttura del modello, con alcuni ambiti nominati (non tutti necessari per l'esempio) che illustrano il mio approccio e indicano i miei problemi. (Si prega di perdonare eventuali errori di sintassi)
class Man < ActiveRecord::Base
has_many :wives
named_scope :has_wife_named lambda { |n| { :conditions => { :wives => {:name => n}}}}
named_scope :has_young_wife_named lambda { |n| { :conditions => { :wives => {:name => n, :age => 0..30}}}}
named_scope :has_yw_named_v2 lambda { |n| { :conditions => ["wives.name = ? AND wives.age <= 30", n]}}
named_scope :joins_wives :joins => :wives
named_scope :has_red_cat :conditions => { :cats => {:color => 'red'}}
named_scope :has_cat_of_color lambda { |c| { :conditions => { :cats => {:color => c}}}}
named_scope :has_7yo_cat :conditions => { :cats => {:age => 7}}
named_scope :has_cat_of_age lambda { |a| { :conditions => { :cats => {:age => a}}}}
named_scope :has_cat_older_than lambda { |a| { :conditions => ["cats.age > ?", a] }}
named_scope :has_cat_younger_than lambda { |a| { :conditions => ["cats.age < ?", a] }}
named_scope :has_cat_fatter_than lambda { |w| { :conditions => ["cats.weight > ?", w] } }
named_scope :joins_wives_cats :joins => {:wives => :cats}
end
class Wife < ActiveRecord::Base
belongs_to :man
has_many :cats
end
class Cat < ActiveRecord::Base
belongs_to :wife
end
posso trovare uomini le cui mogli hanno gatti che sono rossi e sette anni
@men = Man.has_red_cat.has_7yo_cat.joins_wives_cats.scoped({:select => 'DISTINCT men'})
E posso nemmeno a trovare gli uomini le cui mogli hanno gatti che sono più di 20 chili e oltre 6 anni
@men = Man.has_cat_fatter_than(20).has_cat_older_than(5).joins_wives_cats.scoped({:select => 'DISTINCT men'})
Ma non è quello che voglio. Voglio trovare gli uomini le cui mogli hanno tra loro almeno un gatto rosso e un gatto di sette anni, che non deve essere lo stesso gatto, o trovare gli uomini le cui mogli hanno tra loro almeno un gatto sopra un dato peso e un gatto più vecchio di una certa età.
(negli esempi successivi, si prega di ipotizzare la presenza del competentejoins_
eDISTINCT
)posso trovare uomini con mogli di nome Esther
@men = Man.has_wife_named('Esther')
posso anche trovare uomini con mogli di nome Esther, Ruth O Ada (dolce!)
@men = Man.has_wife_named(['Esther', 'Ruth', 'Ada'])
ma voglio trovare uomini con mogli di nome Esther e Ruth e Ada.
Ah ah, solo scherzando, in realtà, ho bisogno di questo: riesco a trovare uomini con mogli sotto i 30 anni di nome Esther
@men = Man.has_young_wife_named('Esther')
Trova ragazzo con i giovani mogli di nome Esther, Ruth o Ada
@men = Man.has_young_wife_named(['Esther', 'Ruth', 'Ada'])
ma come sopra voglio trovare uomini con giovani mogli di nome Esther e Ruth e Ada. Fortunatamente, in questo caso è stato fissato il minimo, ma sarebbe bello specificare anche un'età minima.
c'è un modo per testare una disuguaglianza con una sintassi hash, o avete sempre ripristinare
:conditions => ["", n]
- notare la differenza trahas_young_wife_named
ehas_yw_named_v2
- mi piace la prima meglio, ma la gamma funziona solo per finita valori. Se stai cercando una vecchia moglie, immagino che potresti usare loa..100
ma poi quando una moglie compie 101 anni lascia la ricerca. (hmm.lei può cucinare? j/k)esiste un modo per utilizzare un ambito nell'ambito di un ambito? Mi piacerebbe che se
:has_red_cat
fosse in grado di utilizzare:has_cat_of_color
in qualche modo, o se ci fosse un modo per utilizzare l'ambito da un record figlio nel suo genitore, così avrei potuto inserire gli ambiti relativi al gatto nel modelloWife
.
io davvero non voglio fare questo in SQL dritto senza usare named_scope
, a meno che non ci sia qualcos'altro in realtà più bello - suggerimenti per plugin e quant'altro molto apprezzato, o la direzione in quella sorta di SQL Ho bisogno di imparare. Un amico ha suggerito che le UNION o le sotto-ricerche funzionerebbero qui, ma quelle non sembrano essere discusse molto nel contesto di Rails. Non so ancora nulla delle opinioni - sarebbero utili? C'è un modo rotaie felice di farli?
Grazie!
Mentre stavo andando a St Ives
ho incontrato un uomo con sette mogli
Ogni moglie aveva sette sacchi
Ogni sacco aveva sette gatti
Ogni gatto aveva sette kit
Kit, gatti, sacchi, mogli
Quanti stavano andando a St Ives?
E 'una domanda molto interessante in astratto. E capisco che i nomi dei modelli e degli obiettivi sono derivati da una filastrocca. Ma è sconvolgente, per me. Moglie: appartiene all'uomo? Sul serio? –
sì, ci ho pensato quando lo stavo scrivendo, ma il poema mi era saltato in testa e non riuscivo a liberarmene. –
Mi piacerebbe trovare un buon modo per fare 'UNION's in ambiti denominati in AR. So che puoi farli in SQLAlchemy. – mikelikespie