Incapsulare SQL in un nome_scope
-
02-07-2019 - |
Domanda
Mi chiedevo se ci fosse un modo per usare " find_by_sql " all'interno di un named_scope. Vorrei trattare sql personalizzato come named_scope in modo da poterlo concatenare ai miei names_scopes esistenti. Sarebbe anche utile per ottimizzare uno snippet sql che uso frequentemente.
Soluzione
Mentre puoi inserire qualsiasi SQL che ti piace nelle condizioni di un ambito denominato, se poi chiami find_by_sql
, gli 'ambiti' vengono eliminati.
Data:
class Item
# Anything you can put in an sql WHERE you can put here
named_scope :mine, :conditions=>'user_id = 12345 and IS_A_NINJA() = 1'
end
Funziona (inserisce solo la stringa SQL lì dentro - se ne hai più di una, vengono unite con AND)
Item.mine.find :all
=> SELECT * FROM items WHERE ('user_id' = 887 and IS_A_NINJA() = 1)
Tuttavia, questo non
Items.mine.find_by_sql 'select * from items limit 1'
=> select * from items limit 1
Quindi la risposta è " No " ;. Se pensi a cosa deve succedere dietro le quinte, allora ha molto senso. Al fine di costruire le rotaie SQL deve sapere come si adatta
Quando si creano query normali, select
, join
, condizioni
, ecc. Sono tutti suddivisi in parti distinte. Rails sa che può aggiungere cose alle condizioni senza influire su tutto il resto (che è come funzionano with_scope
e named_scope
).
Con find_by_sql
, tuttavia, dai semplicemente alle rotaie una grande stringa. Non sa cosa va dove, quindi non è sicuro che entri e aggiunga le cose che dovrebbe aggiungere per far funzionare gli ambiti.
Altri suggerimenti
Questo non risponde esattamente a ciò che ti è stato chiesto, ma potresti esaminare "contruct_finder_sql". Ti consente di ottenere l'SQL di un ambito denominato.
named_scope :mine, :conditions=>'user_id = 12345 and IS_A_NINJA() = 1'
named_scope :additional {
:condtions => mine.send(:construct_finder_sql,{}) + " additional = 'foo'"
}
sicuro perché no
: named_scope: condizioni = > [tuo sql]