0

I'm writing a script to alter a bunch of tables at once in an app. But I'm stuck trying to write to the migration file that I'm generating,

here's what I have in the tool:

system "rails g migration AddDefaultValueToBooleans"
file = "#{Rails.root}db/migrate/*add_default_value_to_booleans.rb"

def replace(filepath, regexp, *args, &block)
  content = File.read(filepath).gsub(regexp, *args, &block)
  File.open(filepath, 'wb') { |file| file.write(content) }
end

replace( file, /^def change/mi) { |match| "change_column :my_table, :my_column, null: false, default: false" } 

replace is a nifty little method i found here https://stackoverflow.com/a/2141540/8480602

but it's not finding my file. i keep getting the error
No such file or directory @ rb_sysopen - root_path/migrate/*add_default_value_to_booleans.rb (Errno::ENOENT)

the filepath i'm using is wrong, but I can't seem to figure out how to write it correctly

Andrew Algard
  • 105
  • 1
  • 12

2 Answers2

1

just got a spurt of inspiration after posting this. Not sure if there's a better way of finding the filename, but this works.

Dir[Rails.root.join('db/migrate/*.rb').to_s].each do |filename|
 if filename.include? "add_default_value_to_booleans"
  file =  filename 
 end
end

the main issue here is if there's a lot of migrations it could be fairly inefficient.

Andrew Algard
  • 105
  • 1
  • 12
  • You could search for it beginning from the last created and stop on the first match. You will be creating the file just before running the script so it should be one of the last ones! – EmmanuelB Oct 26 '18 at 20:39
1

I used this other answer to help and solve this problem. Your migration file will contain an almost random timestamp. You need to look for all the files inside db/migrate and get the correct name for the one (or ones) you are looking for.

You dont need to initialize the path before the block, it is sufficient to know the name of the file and its location.

system "rails g migration AddDefaultValueToBooleans"

def replace(filename, regexp, *args, &block)
  matching_files = []
  Find.find('db/migrate') do |path|
    matching_files << path if path.include? 'add_default_value_to_booleans.rb'
  end

  # then for every file found
  matching_files.each do |filepath|
   content = File.read(filepath).gsub(regexp, *args, &block)
   File.open(filepath, 'wb') { |file| file.write(content) }
  end
end

replace( file, /^def change/mi) { |match| "change_column :my_table, :my_column, null: false, default: false" }
EmmanuelB
  • 1,236
  • 9
  • 19