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と「undefined method `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 を作成するよりも、SequelDataMapperなどの ORM を使用することを強くお勧めします。私は Sequel を好みますが、どちらの場合も、ORM がクエリを記述する必要がないという利点があります。アクセスするデータベースとテーブルを指定すると、スキーマと関係が理解されます。Rails を使用している場合、Rails と組み合わせた ActiveRecord は優れた ORM です。別々に使用することもできますが、Rails を使用していない場合は、最初に他の 2 つを使用することをお勧めします。

于 2012-12-28T16:18:45.660 に答える