我有一个字符串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 }
在这里,我不希望评估。
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
答案 0 :(得分:2)
您的字符串看起来非常接近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,确保将其包装在数组中并将数组中可能的字符串转换为整数。
答案 1 :(得分:1)
我对我首选的方法发表了评论:按原样完成参数设置是不寻常的,而理想的方法是解决此问题。使用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]
希望这很有用,请让我知道您的生活状况或有任何疑问。