I have a patient who has first_name and last_name and a medical_record which belongs to patient schemas patient and record
I have the following (simplified) schemas and fields
patient:
last_name
first_name
medical_record:
patient_id
code
All the fields are strings
In the index page there is a single input field for the search criteria where the user types fragments of text.
Having the following data
code
LEWIS HAMILTON 44
MAX VERSTAPPEN 33
SEBASTIAN VETTEL 5
NICO HULKENBERG 27
DANIEL RICCIARDO 3
DANIIL KYVAT 26
I have the following results
Search criteria: H
LEWIS HAMILTON 44
NICO HULKENBERG 27
Search criteria: VE
MAX VERSTAPPEN 33
SEBASTIAN VETTEL 5
Search criteria: VE 3
MAX VERSTAPPEN 33
Search criteria: VE MA
MAX VERSTAPPEN 33
Search criteria: VE MA 456
(EMPTY)
Search criteria: 3
MAX VERSTAPPEN 33
DANIEL RICCIARDO 3
The final SQL statement should look like this
SELECT * FROM patients as p
INNER JOIN medical_records as mr ON mr.patient_id = p.id
WHERE (p.last_name = 'VE' OR p.first_name = 'VE' or mr.code = 'VE')
AND (p.last_name = 'MA' OR p.first_name = 'MA' or mr.code = 'MA')
AND ...
The idea is to chain condition groups with AND for each of the search params.
Here is what I have done in elixir
def search_patients(search_params) do
q =
from p in Patient,
join: r in MedicalRecord,
on: p.id == r.patient_id,
order_by: [p.last_name, p.first_name]
params =
search_params
|> String.split()
q =
params
|> Enum.reduce(q, &filter/2)
IO.inspect(Repo.to_sql(:all, q))
end
def filter(param, query) do
from p in query,
where: p.last_name == ^param,
or_where: p.first_name == ^param
end
However, using “VE MA” as search_params the resulting SQL is as follows:
{"SELECT p0.id, p0.first_name, p0.last_name
FROM patient AS p0 INNER JOIN medical_records AS m1 ON p.id = m1.patient_id
WHERE ((((p0.last_name = $1)) OR (p0.first_name = $2)) AND (p0.last_name = $3)) OR (p0.first_name = $4)",
["VE", "VE", "MA", "MA"]}
Which is not what I expected.
What am I doing wrong?
How can I add a test against medical_record in the filter function? Until now I have only used patient.
Currently I am using a normal comparison (==). How do I introduce LIKE?