我试图在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
答案 0 :(得分: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(", ")
答案 1 :(得分: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代码的方法。