1

我有这个 YAML 条目;

table:
  - name: table_a
select:
  - id: source.id
  - code: source.code
  - name: source.name
  - is_active: TRUE

我需要将它读入一个 HASH 数组并构造一个这样的 SELECT SQL 语句;

SELECT 
  source.id as id,
  source.code as code,
  source.name as name,
  TRUE as is_active
FROM table_a

我正在努力访问 HASH |key,value| 动态配对。

我使用了这段代码;

yml = YAML.load_file("file.yml")
yml.each_pair { |key, value| puts "#{key} = #{value}"}

但是当我使用yml['select'].each_pair我得到“未定义的方法`each_pair'”错误。

4

1 回答 1

3

基于 YAML,解析它的方法如下:

asdf = YAML.load('table:
  - name: table_a
select:
  - id: source.id
  - code: source.code
  - name: source.name
  - is_active: TRUE
  - created_at: Time.now()
  - updated_at: Time.now()')
=> {"table"=>[{"name"=>"table_a"}],
 "select"=>
  [{"id"=>"source.id"},
   {"code"=>"source.code"},
   {"name"=>"source.name"},
   {"is_active"=>true},
   {"created_at"=>"Time.now()"},
   {"updated_at"=>"Time.now()"}]}

您的 YAML 没有创建易于解析的数据结构,这使您跳过箍来访问元素:

asdf['table'][0]['name']
=> "table_a"

asdf['select'][4]['created_at']
=> "Time.now()" 

相反,它应该看起来像:

table:
  name: table_a
select:
  id: source.id
  code: source.code
  name: source.name
  is_active: TRUE
  created_at: Time.now()
  updated_at: Time.now()

解析后,它将创建一个哈希哈希,如下所示:

{
  "table"=>{
    "name" => "table_a"
  },
  "select" =>
  {
    "id"         => "source.id",
    "code"       => "source.code",
    "name"       => "source.name",
    "is_active"  => true,
    "created_at" => "Time.now()",
    "updated_at" => "Time.now()"
  }
}

这使您可以轻松且非常直观地访问元素:

asdf['table']
=> {"name"=>"table_a"}
asdf['select']['created_at']
=> "Time.now()"

YAML 不会将字符串"Time.now()"转换为 RubyTime.now方法调用,因此将该字符串编码为 YAML 数据也无济于事。

相反,在解析它之后,使用:

time_now = Time.now
select = asdf['select']
select['created_at'] = time_now
select['updated_at'] = time_now

"Time.now()"您可以通过预先操作传入的 YAML来更新您的字符串,然后对其进行解析:

yaml_string = '
table:
  name: table_a
select:
  id: source.id
  code: source.code
  name: source.name
  is_active: TRUE
  created_at: Time.now()
  updated_at: Time.now()
'
yaml_string.gsub!('Time.now()', Time.now.to_s)

结果是:

table:
  name: table_a
select:
  id: source.id
  code: source.code
  name: source.name
  is_active: TRUE
  created_at: 2012-12-28 10:09:21 -0700
  updated_at: 2012-12-28 10:09:21 -0700

现在解析它返回:

=> {"table"=>{"name"=>"table_a"},
 "select"=>
  {"id"=>"source.id",
   "code"=>"source.code",
   "name"=>"source.name",
   "is_active"=>true,
   "created_at"=>2012-12-28 10:09:21 -0700,
   "updated_at"=>2012-12-28 10:09:21 -0700}}

YAML 可以用那个时间值做一些事情,因为它可以识别它:

[14] pry(main)> asdf['select']['created_at']
=> 2012-12-28 10:09:21 -0700
[15] pry(main)> asdf['select']['created_at'].class
=> Time

此外,我强烈建议不要编写自己的 SQL,而是使用 ORM,例如SequelDataMapper。我喜欢 Sequel,但无论哪种情况,优点是您不必编写查询,ORM 可以。您告诉它要访问哪些数据库和表,它会计算出架构和关系。如果您使用的是 Rails,ActiveRecord 是一个很好的 ORM,它与 Rails 相结合。它可以单独使用,但如果你不使用 Rails,我会先推荐另外两个。

于 2012-12-28T16:18:45.660 回答