新手问题 不用 eval 的情况下,怎样将字符串转成 array 或者 hash

lehug · 2017年06月28日 · 最后由 lehug 回复于 2017年10月30日 · 1505 次阅读

前端有一个时间控件,选择一个时间段,传入后端为一个数组,长度为 2,正常的 controller 可以将这个参数正常解析为数组。 但是我借用 ransack 然后在 config/initializers/ransack.rb 中定义如下方法:

Ransack.configure do |config|
  config.add_predicate 'between',
    arel_predicate: 'between',
    formatter: proc { |v|
    parts = eval(v) 
      OpenStruct.new(begin: parts['0'].to_time, end: parts['1'].to_time)
    },
    validator: proc { |v| v.present? },
    type: :string
end

其中 formatter 中拿到的 v,内容类似: '{"0"=>"Mon Jun 26 2017 16:31:43 GMT+0800", "1"=>"Mon Jul 31 2017 16:31:43 GMT+0800"}',是一个 string 类型。

如上 eval 处理可以将其解析为 hash,请问 eval 外有方法解析这个字符串吗?

两个点:

  • 可以尝试传两个参数,这样就能避免后端改造
  • 字符串可以正则或者 split 来解析

看看这里的思路http://blog.lingceng.io/blog/2015/12/28/query-date-range-with-ransack/

给你一个逗 B 得解决方法: a = '{"0"=>"Mon Jun 26 2017 16:31:43 GMT+0800", "1"=>"Mon Jul 31 2017 16:31:43 GMT+0800"}' hash = Hash[*(a.gsub(/[{}]/,'').gsub('=>',',').split(','))] 😀 😀 @jiyuhang110 我记得你那本书里貌似有类似的问题 帮忙翻翻😙

感觉返回的是 json

lingceng 回复

用的 ant.design 的日期选择组件,前端不方便改造。这个思路可以,还在研究 ransack,希望从初始化的参数中找到答案

sevk 回复

JSON.parse(a) 会报错,这个是钩子拿到的局部变量,是一个 string

gem install parser
#test.rb
require 'parser/current'

nodes = Parser::CurrentRuby.parse( '{"0"=>"Mon Jun 26 2017 16:31:43 GMT+0800", "1"=>"Mon Jul 31 2017 16:31:43 GMT+0800"}')
=begin
=> s(:hash,
  s(:pair,
    s(:str, "0"),
    s(:str, "Mon Jun 26 2017 16:31:43 GMT+0800")),
  s(:pair,
    s(:str, "1"),
    s(:str, "Mon Jul 31 2017 16:31:43 GMT+0800")))
=end

children[0].children[1].children
#=> ["Mon Jun 26 2017 16:31:43 GMT+0800"]

跟踪代码发现 ransack 基于安全,将 json 转为 string 传递给了 formatter,这个问题暂且用 eval 处理,暂且关闭

lehug 关闭了讨论。 10月30日 10:11
需要 登录 后方可回复, 如果你还没有账号请 注册新账号