Created
February 22, 2016 11:02
-
-
Save vala/7c82ae8b8b5a354e2291 to your computer and use it in GitHub Desktop.
Simple script to allowing to migrate hardcoded URLs in model fields to other hosts
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env ruby | |
# | |
# This script allows for parsing every models of your app, looking for string | |
# and text fields, then replacing every previous hardcoded URL with a new | |
# URL reflecting your new assets location | |
# | |
# Example usage : | |
# | |
# # Replace all URLs targeting an S3 bucket to a locale system URL | |
# rake replace_models_assets_url MATCHER="http://s3.amazonaws.com/mybucket/" REPLACEMENT="/system/" | |
# | |
class ModelsAssetsURLReplacer | |
def initialize | |
eager_load_models! | |
end | |
def run | |
ask_user_confirmation! | |
models.each do |model| | |
next unless model.table_name.present? | |
ModelReplacer.new(model).replace! | |
end | |
end | |
private | |
def eager_load_models! | |
# Eager load all models | |
$LOAD_PATH.each do |path| | |
next unless path.to_s.match(/\/models/) | |
Dir[File.join(path, '**', '*.rb')].each do |file| | |
load(file) | |
end | |
end | |
end | |
def models | |
@models ||= ActiveRecord::Base.descendants | |
end | |
def ask_user_confirmation! | |
answer = ask "Every string found in your models starting with \"#{ ENV['MATCHER'] }\" " + | |
"will be replaced with a starting \"#{ ENV['REPLACEMENT'] }\". " + | |
"Are you sure ? (y/n) " | |
if answer.match(/^y/i) | |
puts "\n" # Jump a line | |
else | |
puts "Aborted !" | |
Process.exit | |
end | |
end | |
def ask(question) | |
print question | |
STDIN.gets | |
end | |
end | |
class ModelReplacer | |
attr_reader :model, :changes_count | |
def initialize(model) | |
@model = model | |
@changes_count = 0 | |
end | |
def replace! | |
print "Replace URLs for model : #{ model.name } ... " | |
model.find_each do |resource| | |
attributes = text_columns.each_with_object({}) do |column, hash| | |
if (value = resource.send(column)) && String === value | |
hash[column] = value.gsub(ENV['MATCHER'], ENV['REPLACEMENT']) | |
end | |
end | |
resource.assign_attributes(attributes) | |
@changes_count += 1 if resource.changed? | |
resource.save(validate: false) | |
end | |
puts "Done ! #{ changes_count } rows changed." | |
end | |
private | |
def text_columns | |
@text_columns ||= model.columns.select { |c| | |
c.type.in?([:string, :text]) | |
}.map(&:name) | |
end | |
end | |
task replace_models_assets_url: :environment do |t, args| | |
# Run the script | |
ModelsAssetsURLReplacer.new.run | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment