Rails Dynamic «Где» - PullRequest
       14

Rails Dynamic «Где»

1 голос
/ 27 сентября 2019

У меня есть поле поиска, где пользователь может ввести «Param1», и мой контроллер содержит:

Model.where('column_name LIKE ?', "%#{search_field}%")

Это преобразуется в:

SELECT ... FROM table WHERE column_name LIKE '%Param1%'

Это прекрасно работает, если пользователь вводит «Param1», но я хочу сделать это поле поиска через запятую.

Так, если пользователь вводит «Param1, param2» или «Param1, Param2, Param3», предложение WHERE LIKE должно работать, Моя идея состоит в том, чтобы разбить строку на основе ',' и совершенно не иметь представления о том, как построить здесь предложение Model.where, поскольку это может быть 1 параметр или 4.

Ответы [ 4 ]

2 голосов
/ 27 сентября 2019

Если вы используете PostgreSQL, вы можете использовать ЛЮБОЙ, передавая сопоставленный массив параметров:

Model.where('name LIKE ANY(array[?])', params.split(',').map { |val| "%#{val}%" })
# SELECT "models".*
# FROM "models"
# WHERE (name LIKE ANY(array['%param1%','%param2%']))
2 голосов
/ 27 сентября 2019

Это то, что я делаю в одном проекте:

values = search_field.split(',').map { |x| "%#{x}%" } # split values and add "%...%"
count = values.count # count them

# create an array of LIKE operators depending on the values counted
# if count is 2 then it will be an array: ['column_name LIKE ?', 'column_name LIKE ?']
where_sql_arr = count.times.map{'column_name LIKE ?'} 

# create the sql query joining with " OR "
# 'column_name LIKE ? OR column_name LIKE ?'
where_sql = where_sql_arr.join(' OR ') 

Model.where(where_sql, *values) # note the * before "values" to split the array into multiple arguments
2 голосов
/ 27 сентября 2019

В ответе используется тот же метод, что и в ответе arieljuod , но вместо * простых строк используется Arel API .

values = search_field.split(',')
column_name = Model.arel_table[:column_name]
query = values.map { |value| column_name.matches("%#{value}%") }.reduce(:or)
Model.where(query)
1 голос
/ 27 сентября 2019

Разделение параметров - хорошая идея.

conditions = "Param1,Param2,Param3, Param4".gsub(" ","").split(',')

Если достаточно поиска без масок или регулярных выражений, вы можете использовать запрос IN или AR: Model.where(column_name: conditions)

В противном случае (по крайней мере, в postgresql) код немного усложняется.

Построить строку запроса из входной строки:

conditions = "Param1,Param2,Param3, Param4".gsub(" ","").split(',')

query = ("column_name ~* ? OR " * conditions.size)[0...-3] # Delete last unterminated " OR"

И наконец

Model.where(query, *conditions) # splat operator (*) converts array into argument list

Должно работать.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...