2012-06-29 107 views
1

我試圖在每個循環的每行結尾處插入一個逗號作爲紅寶石。我不想在最後一行輸入逗號。我知道array.join(',')特性,但在這種情況下我有點困惑。Ruby每個循環的最後迭代

我該如何重構我的第一次嘗試去做我需要的東西?

重要的行

@headers.each do |header| 
      file.puts "`#{table[:source_database]}`.`#{table[:current_name]}`.`#{header[:current_name]}` AS `#{header[:magi_name]}`#{("," unless @headers.last == header)}" if header[:table_id] == table[:id] 
     end 

全類

class Table < ActiveRecord::Base   
    has_many :headers 

    #--------------------------------------------------------------------------------------------------# 

    def self.generate 
    @tables = Table.select([:id, :source_database, :current_name, :magi_name]) 
    @headers = Header.select([:id, :table_id, :current_name, :magi_name]) 

    File.new("magi_generation.sql", "w") 
    @tables.each do |table| 
     File.open("magi_generation.sql", "a+") do |file| 
     file.puts "#Drops current view #{table[:magi_name]} and then recreates it using updated columns" 
     file.puts "DROP VIEW IF EXISTS `#{table[:magi_name]}`;" 
     file.puts "CREATE ALGORITHM=UNDEFINED DEFINER=`user`@`127.0.0.1` SQL SECURITY DEFINER VIEW `#{table[:magi_name]}`" 
     file.puts "AS select" 
     @headers.each do |header| 
      file.puts "`#{table[:source_database]}`.`#{table[:current_name]}`.`#{header[:current_name]}` AS `#{header[:magi_name]}`#{("," unless @headers.last == header)}" if header[:table_id] == table[:id] 
     end 
     file.puts "FROM `#{table[:source_database]}`.`#{table[:current_name]}`;" 
     file.puts "" 
     end 
    end 

    end 

end 
+0

使用each_with_index並查看索引是否是最後一個? –

+0

因此更改爲@ tables.each_with_index do | table,index |然後如果index.last ==什麼?我幾乎已經掌握了這些概念,但還沒有完全實現。 – jwg2s

+0

index是一個數字,因此您應該將它與一個數字進行比較,例如:index == @ tables.length-1,那麼您應該得到「是最後一個元素」的布爾值 – robustus

回答

7

您可以使用each_with_index,讓你當前元素和索引。這樣,您可以比較數組的大小和當前元素。

但是,我不喜歡這種方法。在你的情況下,這不是乾淨的,因爲你正在過濾循環內的記錄。我寧願過濾記錄,然後只循環有效記錄。

file.puts @headers. 
    # keep only elements where the condition matches 
    select { |header| header[:table_id] == table[:id] }. 
    # convert each element into a line 
    map { |header| "`#{table[:source_database]}`.`#{table[:current_name]}`.`#{header[:current_name]}` AS `#{header[:magi_name]}`" }. 
    # merge everything into a single string 
    join(", ") 
+0

+1,功能更多,更清晰。 –

+0

+1,你打我3分鐘:) – dbenhur

+0

謝謝,這工作得很好!這正是我想要完成的,但在概念上並不存在。 – jwg2s

1

處理一切就像你想要的,在最後放置一個逗號和換行符並將其放入一個String變量中。完成後,chop關閉字符串的最後兩個字符,然後將其寫入文件。

for_file = "" 
@header.each do |header| 
    for_file << header + ",\n" 
end 
for_file.chop.chop # Gets rid of last newline and comma 
file.puts for_file 

我意識到我的例子循環不包括您在您的循環在做什麼的程度,但它把重要的事情它在一個字符串,然後.chop.chop

此外,不是每個新行都有file.puts ...,而是考慮一個heredoc。

file.puts <<EOF 
SELECT 'nothing' 
FROM dual 
UNION 
SELECT 'something' 
FROM dual; 
EOF 

它可能會使您的SQL更具可讀性,您仍然可以使用字符串插值。

這是我如何在我自己的腳本中使用字符串插值生成SQL代碼。