From 7789842174e77eeb619562b66cd29e80baeb3145 Mon Sep 17 00:00:00 2001 From: Ben Tillman Date: Wed, 16 Nov 2011 16:41:06 +0800 Subject: [PATCH 1/4] Rake task to migrate super_tags --- lib/tasks/super_tags.rake | 78 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 78 insertions(+) create mode 100755 lib/tasks/super_tags.rake diff --git a/lib/tasks/super_tags.rake b/lib/tasks/super_tags.rake new file mode 100755 index 0000000000..5732944992 --- /dev/null +++ b/lib/tasks/super_tags.rake @@ -0,0 +1,78 @@ +namespace :super_tags do + + desc "Migrate super_tags plugin to core custom_fields" + task :migrate => :environment do + def dryrun? + true + #~ ENV['DRYRUN'] == 'true' + end + + connection = ActiveRecord::Base.connection + + columns = %w(tag_id field_name field_type field_label table_name select_options max_size required disabled form_field_type field_info) + + field_data = connection.select_all "SELECT #{columns.join(', ')} FROM customfields" + + group_ids = {} + + tag_ids = field_data.map {|row| row['tag_id']}.uniq + tag_ids.each do |tag_id| + tag = ActsAsTaggableOn::Tag.find(tag_id) + group_params = {:tag_id => tag.id, :name => tag.name} + if dryrun? + puts group_params + else + group = CustomFieldGroup.create group_params + group_ids[tag_id] = group.id + end + end + + field_data.each do |row| + if (table_name = row['table_name']).present? + field_params = { + :klass_name => table_name.singularize.camelize, + :name => row['field_name'], + :label => row['field_label'], + :position => row['position'], + :collection => row['select_options'], + :on => row['form_field_type'], + :hint => row['field_info'], + :required => row['required'], + :disabled => row['disabled'], + :maxlength => row['max_size'], + :field_group_id => group_ids[row['tag_id']] + } + if dryrun? + puts field_params + else + field = CustomField.create field_params + end + end + end + + tag_ids.each do |tag_id| + data = connection.select_all "SELECT * FROM tag#{tag_id}s" + keys = data.first.keys.reject {|k| %w(id customizable_type).include?(k)} + + klass_names = data.map {|row| row['customizable_type']}.uniq + klass_names.each do |klass_name| + klass = klass_name.constantize + values = data.map do |row| + keys.map {|k| row[k] =~ /^\d$/ ? row[k] : "'#{row[k]}'"}.join(', ') + end + keys.shift # We don't need customizable_id anymore + + insert = %Q{ + INSERT INTO #{klass.table_name} (#{([klass.primary_key] + keys).join(', ')}) + VALUES (#{values.join('), (')}) + ON DUPLICATE KEY UPDATE #{keys.map {|k| "#{k} = VALUES(#{k})"}.join(', ')} + } + if dryrun? + puts insert + else + connection.execute insert + end + end + end + end +end From 0a83f9c86a81e8648d30a0e71765febf9770ef07 Mon Sep 17 00:00:00 2001 From: Ben Tillman Date: Wed, 16 Nov 2011 21:37:29 +0800 Subject: [PATCH 2/4] Added tag_id to field_groups and fix some bugs in the super_tags migration --- .../20111116091952_add_field_groups_tag_id.rb | 9 ++++ lib/tasks/super_tags.rake | 44 +++++++++---------- 2 files changed, 31 insertions(+), 22 deletions(-) create mode 100644 db/migrate/20111116091952_add_field_groups_tag_id.rb diff --git a/db/migrate/20111116091952_add_field_groups_tag_id.rb b/db/migrate/20111116091952_add_field_groups_tag_id.rb new file mode 100644 index 0000000000..975a23becd --- /dev/null +++ b/db/migrate/20111116091952_add_field_groups_tag_id.rb @@ -0,0 +1,9 @@ +class AddFieldGroupsTagId < ActiveRecord::Migration + def self.up + add_column :field_groups, :tag_id, :integer + end + + def self.down + remove_column :field_groups, :tag_id + end +end diff --git a/lib/tasks/super_tags.rake b/lib/tasks/super_tags.rake index 5732944992..670a1eca2d 100755 --- a/lib/tasks/super_tags.rake +++ b/lib/tasks/super_tags.rake @@ -3,8 +3,7 @@ namespace :super_tags do desc "Migrate super_tags plugin to core custom_fields" task :migrate => :environment do def dryrun? - true - #~ ENV['DRYRUN'] == 'true' + ENV['DRYRUN'] == 'true' end connection = ActiveRecord::Base.connection @@ -18,11 +17,11 @@ namespace :super_tags do tag_ids = field_data.map {|row| row['tag_id']}.uniq tag_ids.each do |tag_id| tag = ActsAsTaggableOn::Tag.find(tag_id) - group_params = {:tag_id => tag.id, :name => tag.name} + group_params = {:tag_id => tag.id, :name => tag.name + ' Details'} if dryrun? puts group_params else - group = CustomFieldGroup.create group_params + group = FieldGroup.create group_params group_ids[tag_id] = group.id end end @@ -51,26 +50,27 @@ namespace :super_tags do end tag_ids.each do |tag_id| - data = connection.select_all "SELECT * FROM tag#{tag_id}s" - keys = data.first.keys.reject {|k| %w(id customizable_type).include?(k)} + if (data = connection.select_all "SELECT * FROM tag#{tag_id}s").present? + keys = data.first.keys.reject {|k| %w(id customizable_type).include?(k)} - klass_names = data.map {|row| row['customizable_type']}.uniq - klass_names.each do |klass_name| - klass = klass_name.constantize - values = data.map do |row| - keys.map {|k| row[k] =~ /^\d$/ ? row[k] : "'#{row[k]}'"}.join(', ') - end - keys.shift # We don't need customizable_id anymore + klass_names = data.map {|row| row['customizable_type']}.uniq + klass_names.each do |klass_name| + klass = klass_name.constantize + values = data.map do |row| + keys.map {|k| row[k] =~ /^\d*$/ ? row[k] : "'#{row[k].gsub("'","''")}'"}.join(', ') + end + keys.shift # We don't need customizable_id anymore - insert = %Q{ - INSERT INTO #{klass.table_name} (#{([klass.primary_key] + keys).join(', ')}) - VALUES (#{values.join('), (')}) - ON DUPLICATE KEY UPDATE #{keys.map {|k| "#{k} = VALUES(#{k})"}.join(', ')} - } - if dryrun? - puts insert - else - connection.execute insert + insert = %Q{ + INSERT INTO #{klass.table_name} (#{([klass.primary_key] + keys).join(', ')}) + VALUES (#{values.join('), (')}) + ON DUPLICATE KEY UPDATE #{keys.map {|k| "#{k} = VALUES(#{k})"}.join(', ')} + } + if dryrun? + puts insert + else + connection.execute insert + end end end end From 1274e56e39334f7d8c3789ce6e4486f1da8feb09 Mon Sep 17 00:00:00 2001 From: Ben Tillman Date: Thu, 17 Nov 2011 13:30:36 +0800 Subject: [PATCH 3/4] Data import for super_tags --- ...041311_change_fields_collection_to_text.rb | 9 ++ lib/tasks/super_tags.rake | 128 +++++++++++------- 2 files changed, 88 insertions(+), 49 deletions(-) create mode 100644 db/migrate/20111117041311_change_fields_collection_to_text.rb diff --git a/db/migrate/20111117041311_change_fields_collection_to_text.rb b/db/migrate/20111117041311_change_fields_collection_to_text.rb new file mode 100644 index 0000000000..f1fb86894c --- /dev/null +++ b/db/migrate/20111117041311_change_fields_collection_to_text.rb @@ -0,0 +1,9 @@ +class ChangeFieldsCollectionToText < ActiveRecord::Migration + def self.up + change_column :fields, :collection, :text + end + + def self.down + change_column :fields, :collection, :string + end +end diff --git a/lib/tasks/super_tags.rake b/lib/tasks/super_tags.rake index 670a1eca2d..f91dbacf00 100755 --- a/lib/tasks/super_tags.rake +++ b/lib/tasks/super_tags.rake @@ -3,76 +3,106 @@ namespace :super_tags do desc "Migrate super_tags plugin to core custom_fields" task :migrate => :environment do def dryrun? + #~ true ENV['DRYRUN'] == 'true' end - connection = ActiveRecord::Base.connection - columns = %w(tag_id field_name field_type field_label table_name select_options max_size required disabled form_field_type field_info) + map_as = { + 'short_answer' => 'string', + 'number' => 'decimal', + 'long_answer' => 'text', + 'select_list' => 'select', + 'multi_select' => 'check_boxes', + 'checkbox' => 'checkbox', + 'date' => 'date', + 'datetime' => 'datetime' + } + group_ids = {} + updates = [] - field_data = connection.select_all "SELECT #{columns.join(', ')} FROM customfields" + connection = ActiveRecord::Base.connection - group_ids = {} + field_data = connection.select_all "SELECT #{columns.join(', ')} FROM customfields" tag_ids = field_data.map {|row| row['tag_id']}.uniq tag_ids.each do |tag_id| tag = ActsAsTaggableOn::Tag.find(tag_id) - group_params = {:tag_id => tag.id, :name => tag.name + ' Details'} - if dryrun? - puts group_params - else - group = FieldGroup.create group_params - group_ids[tag_id] = group.id - end - end - - field_data.each do |row| - if (table_name = row['table_name']).present? - field_params = { - :klass_name => table_name.singularize.camelize, - :name => row['field_name'], - :label => row['field_label'], - :position => row['position'], - :collection => row['select_options'], - :on => row['form_field_type'], - :hint => row['field_info'], - :required => row['required'], - :disabled => row['disabled'], - :maxlength => row['max_size'], - :field_group_id => group_ids[row['tag_id']] - } - if dryrun? - puts field_params - else - field = CustomField.create field_params - end - end - end - tag_ids.each do |tag_id| if (data = connection.select_all "SELECT * FROM tag#{tag_id}s").present? - keys = data.first.keys.reject {|k| %w(id customizable_type).include?(k)} + keys = data.first.keys.reject {|k| %w(id customizable_id customizable_type).include?(k)} + + # FieldGroup + unless field_group = FieldGroup.find_by_tag_id(tag.id) + group_params = {:tag_id => tag.id, :name => tag.name + ' Details'} + if dryrun? + puts group_params + else + field_group = FieldGroup.create! group_params + end + end klass_names = data.map {|row| row['customizable_type']}.uniq klass_names.each do |klass_name| klass = klass_name.constantize - values = data.map do |row| - keys.map {|k| row[k] =~ /^\d*$/ ? row[k] : "'#{row[k].gsub("'","''")}'"}.join(', ') + + # CustomField + field_data.each do |row| + next unless row['tag_id'] == tag_id + + unless field = CustomField.find_by_klass_name_and_name(klass_name, row['field_name']) + + collection = row['select_options'].split('|').map(&:strip) if row['select_options'] + + field_params = { + :klass_name => klass_name, + :name => row['field_name'], + :label => row['field_label'], + :position => row['position'], + :collection => collection, + :as => map_as[row['form_field_type']], + :hint => row['field_info'], + :required => row['required'], + :disabled => row['disabled'], + :maxlength => row['max_size'], + :field_group_id => field_group.try(:id) + } + if dryrun? + puts field_params + else + field = CustomField.create! field_params + end + end end - keys.shift # We don't need customizable_id anymore - insert = %Q{ - INSERT INTO #{klass.table_name} (#{([klass.primary_key] + keys).join(', ')}) - VALUES (#{values.join('), (')}) - ON DUPLICATE KEY UPDATE #{keys.map {|k| "#{k} = VALUES(#{k})"}.join(', ')} - } - if dryrun? - puts insert - else - connection.execute insert + # Data + data.each do |row| + values = [] + keys.each do |key| + next unless klass.column_names.include?(key) + + value = if row[key] =~ /^\d+$/ + row[key] + elsif row[key].present? + connection.quote(row[key]) + end + values << "#{key} = #{value}" if value.present? + end + + updates << "UPDATE #{klass.table_name} SET #{values.join(', ')} WHERE #{klass.primary_key} = #{row['customizable_id']}" if values.present? end end end end + + if dryrun? + File.open('update.sql', 'w') do |file| + file << updates.join(";\n") + end + else + updates.each do |update| + connection.execute update + end + end end end From cf7d139ba782e6038fdfb5a5a68fff797358aac1 Mon Sep 17 00:00:00 2001 From: Ben Tillman Date: Thu, 17 Nov 2011 16:12:58 +0800 Subject: [PATCH 4/4] Use boolean rather than checkbox --- app/models/fields/field.rb | 2 +- lib/tasks/super_tags.rake | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/app/models/fields/field.rb b/app/models/fields/field.rb index 98ecdb1669..f09c08dd6b 100644 --- a/app/models/fields/field.rb +++ b/app/models/fields/field.rb @@ -16,7 +16,7 @@ class Field < ActiveRecord::Base 'select' => :string, 'radio' => :string, 'check_boxes' => :text, - 'checkbox' => :boolean, + 'boolean' => :boolean, 'date' => :date, 'datetime' => :timestamp, 'decimal' => [:decimal, {:precision => 15, :scale => 2}], diff --git a/lib/tasks/super_tags.rake b/lib/tasks/super_tags.rake index f91dbacf00..28dd9178ab 100755 --- a/lib/tasks/super_tags.rake +++ b/lib/tasks/super_tags.rake @@ -14,7 +14,7 @@ namespace :super_tags do 'long_answer' => 'text', 'select_list' => 'select', 'multi_select' => 'check_boxes', - 'checkbox' => 'checkbox', + 'checkbox' => 'boolean', 'date' => 'date', 'datetime' => 'datetime' }