2012-12-28 70 views
1

我有這個YAML條目;Ruby:哈希陣列的列名和值對來自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」錯誤。

+2

你究竟在爲什麼而掙扎?你有樣品代碼嗎?你試過什麼了? –

+0

我看不到任何試圖讀取YAML數據的代碼。而且,什麼是「HASH數組」? –

+0

我編輯我的問題,包括示例代碼。我是Ruby新手,如果我不瞭解基礎知識,請耐心等待。 – mevdiven

回答

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()"成一個Ruby Time.now方法調用,所以編碼字符串進入YAML數據將無濟於事。

相反,解析之後,使用方法:

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

您可以通過-操作前傳入YAML,然後解析它更新您的"Time.now()"字符串:

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,我會先推薦其他兩個。

+0

我不能使用select ['created_at'],因爲哈希的「key」具有在運行時更改的動態值 – mevdiven

+0

如果您的密鑰在運行時發生更改,那麼您將不得不編寫一些非常動態的Ruby 。在使用數據庫時,鍵是字段名稱,並且永遠不會更改,並且與鍵關聯的值是字段內容。如果您的密鑰更改您的聲明,聽起來像是代碼與數據庫交談的方式和/或一些寫得不好的代碼混淆。 –