Есть ли какая-либо функция для получения значения массива из строки, кроме `eval`? - PullRequest
0 голосов
/ 13 февраля 2019

У меня есть строка params, значение которой "1" или "['1','2','3','4']".Используя метод eval, я могу получить результат 1 или [1,2,3,4], но мне нужен результат [1] или [1,2,3,4].

params[:city_id] = eval(params[:city_id])

scope :city, -> (params) { params[:city_id].present? ? where(city_id: (params[:city_id].is_a?(String) ? eval(params[:city_id]) : params[:city_id])) : all }

Здесь я не хочу eval.

scope :city, -> (params) { params[:city_id].present? ? where(city_id: params[:city_id]) : all }

params[:city_id] #should be array values e.g [1] or [1,2,3,4] instead of string

Ответы [ 2 ]

0 голосов
/ 13 февраля 2019

Ваши строки выглядят очень близко к JSON, поэтому, вероятно, самое безопасное, что вы можете сделать, это проанализировать строку как JSON.Фактически:

JSON.parse("1") => 1
JSON.parse('["1","2","3","4"]') => ["1","2","3","4"]

Теперь ваш массив использует одинарные кавычки.Поэтому я бы предложил вам сделать следующее:

Array(JSON.parse(string.gsub("'", '"'))).map(&:to_i)

Итак, замените одинарные кавычки на двойные, проанализируйте как JSON, убедитесь, что они заключены в массив, и преобразуйте возможные строки в массиве в целые числа.

0 голосов
/ 13 февраля 2019

Я оставил комментарий к тому, что было бы моим предпочтительным подходом: это необычно, чтобы ваши параметры были такими, какие вы есть, и идеальным подходом было бы решить эту проблему.Использование eval определенно бесполезно - есть некоторые серьезные проблемы с безопасностью (например, представьте, что кто-то отправляет "City.delete_all" в качестве параметра).

В качестве решения вашей непосредственной проблемы вы можете сделать этоиспользуя регулярное выражение, сканируя на наличие цифр:

str = "['1','2','3','4']"
str.scan(/\d+/)
# => ["1", "2", "3"]

str = '1'
str.scan(/\d+/)
# => ["1"]

# In your case:

params[:city_id].scan(/\d+/)

В очень простых сроках это просматривает данную строку для любых цифр, которые там находятся.Вот простой Regex101 с результатами / объяснением: https://regex101.com/r/41yw9C/1.

Rails должен позаботиться о преобразовании полей в последующем запросе (where(city_id: params[:city_id])), хотя, если вам явно нужен массив целых чисел, вы можете добавитьследующее (спасибо @SergioTulentsev):

params[:city_id].scan(/\d+/).map(&:to_i)

# or in a single loop, though slightly less readable:
[].tap { |result| str.scan(/\d+/) { |match| result << match.to_i } }

# => [1, 2, 3, 4]

Надеюсь, что это полезно, дайте мне знать, как вы ладите или если у вас есть какие-либо вопросы.

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