1

我试图在 ruby​​ 的每个循环中的每行末尾插入一个逗号。我不想要最后一行的逗号。我知道 array.join(',') 功能,但在这种情况下我有点困惑。

我如何重构我第一次尝试做我需要的事情?

重要线路

@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
4

2 回答 2

8

您可以使用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(", ")
于 2012-06-29T17:10:04.417 回答
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 代码的方式。

于 2012-06-29T17:25:07.417 回答