Ho creato un sistema di supporto per i nostri sostenitori - programmato con ruby on rails (Ruby 1.9.3 Rails 3.2)
C'è un modello di biglietto con a belongs_to
associazione agli utenti (sostenitore).
Uso la gemma Ransack di Ernie per la ricerca. Quando il sostenitore cerca i propri biglietti (gestiti da tickets_controller.index), dovrebbe anche vedere i ticket non associati nel risultato della ricerca (visualizzazioni / biglietti / indice) (in combinazione con le altre condizioni di serach, ad esempio "data" o altro)
(In modo che possa prendere un biglietto aperto)
dichiarazione SQL prevista:
SELECT * FROM tickets WHERE ... AND (user_id=5 OR user_id IS NULL) AND ...
Provai user_id_null_or_user_id_eq
nel modulo di ricerca della vista indice, ma ciò non funziona (nessun errore di metodo)
Come posso creare un predicato personalizzato (o un ransacker) per risolvere questo problema? (Grazie a @Magnuss per questo commento)
Sfortunatamente, non ho esperienza con Arel
Qualcosa di simile a:
ransacker :user_null_or_eq do
...
end
nel modello dei biglietti.
Spero che questo spieghi il problema in modo più dettagliato.
Grazie per qualsiasi aiuto.
risposte:
5 per risposta № 1Ho anche dovuto capire questo e risposta @ TomGaiutato molto! Non hai davvero bisogno di creare un ransacker per questo problema, è necessario risolverlo usando il metodo build_grouping di ransack (che non è documentato da nessuna parte ...) e inserisci le condizioni di cui hai bisogno con "o" condition.
L'ho usato per cercare elementi da aggiungere a una gabbia ma volevo mostrare all'utente solo gli elementi che non sono già nella mia gabbia (e anche non assegnati ad alcuna altra gabbia), quindi nel mio controller:
@search = Cage.ransack(params[:q])
@search.build_grouping({:m => "or", :storage_id_not_eq => @cage_item.id, :storage_id_null => true})
@results_count = @search.result(:distinct => true).length
@items = @search.result(:distinct => true).paginate(:per_page => 20, :page => params[:page] || 1)
@search.build_condition if @search.conditions.empty?
@search.build_sort if @search.sorts.empty?
Quindi quando stampo la query ransack è in esecuzione mostrerà:
@search.result.to_sql
"SELECT `specimens`.* FROM `specimens` WHERE (`specimens`.`deleted_at` IS NULL) AND ((`specimens`.`storage_id` != 183 OR `specimens`.`storage_id` IS NULL))"
e se aggiungo una query sul nome:
@search.result.to_sql
"SELECT `specimens`.* FROM `specimens` WHERE (`specimens`.`deleted_at` IS NULL) AND ((`specimens`.`name` LIKE "%root%" AND (`specimens`.`storage_id` != 183 OR `specimens`.`storage_id` IS NULL)))"
Spero che questo aiuti te o qualcun altro che ha problemi nell'usare OR in condizioni di saccheggio invece che in AND.
1 per risposta № 2
Potresti creare i tuoi parametri di query come questo
q: {g: [ {m: "or", user_id_eq: 5, user_id_null: 1} ] }
dove questo:
user_id_null: 1
è solo un flag per cercare il valore null
0 per risposta № 3
OK - ecco la mia soluzione - ispirata al graywh (grazie mille): Ransack / temi / 290
È possibile aggiungere un nuovo nodo di raggruppamento -con un "o" -combinatore- all'oggetto di ransack.
Nella vista indice sono cambiato f.select :user_id_eq
a select_tag ...
tickets_controller.index:
@q = Ticket.search(params[:q])
if params[:user_id_eq] && params[:user_id_eq]!=""
@q.build_grouping({:m => "or", :user_id_eq => params[:user_id_eq], :user_id_null => true})
end