этот скрипт сравнивает Object, Arrays и многомерный массив
function compare(a,b){
var primitive=['string','number','boolean'];
if(primitive.indexOf(typeof a)!==-1 && primitive.indexOf(typeof a)===primitive.indexOf(typeof b))return a===b;
if(typeof a!==typeof b || a.length!==b.length)return false;
for(i in a){
if(!compare(a[i],b[i]))return false;
}
return true;
}
. Первая строка проверяет, является ли он примитивным типом. если он сравнивает два параметра.
, если они являются объектами. он выполняет итерацию по объекту и проверяет каждый элемент рекурсивно.
Использование:
var a=[1,2,[1,2]];
var b=[1,2,[1,2]];
var isEqual=compare(a,b); //true
, Если Вы имеете дело с системами производственного класса тогда да, это очень плохо. Если это - Ваш собственный любимый проект, то что-либо позволяется (если ничто иное, это будет полезный опыт:), хотя возможности состоят в том, что как можно скорее, даже в любимом проекте, Вы окажетесь, что помещавший крест по обратной миграции только необходимо отменить ту миграцию несколько дней спустя, быть ею через rake
или вручную.)
В производственном сценарии, Вы должны всегда прилагать усилие для записи и тест обратимая миграция в возможности, что Вы проходите его в производстве, затем обнаруживаете ошибку, которая вынуждает Вас откатывать (код и схема) к некоторому предыдущему пересмотру (ожидающий некоторая нетривиальная фиксация - и в других отношениях неприменимая производственная система.)
Обратные миграции располагаются от главным образом тривиального (удаление столбцов или таблиц, которые были добавлены во время миграции, и/или изменяющий типы столбца, и т.д.) к несколько более включенному (execute
из JOIN
редактор INSERT
с или UPDATE
с, но ничто не так сложно, чтобы выровнять по ширине "развертку его под ковриком". Если ничто иное, вынуждая себя думать о способах достигнуть обратных миграций не может дать Вам новое понимание самой проблемы, которую Ваш вперед решает миграция.
Вы могли бы иногда сталкиваться с ситуацией, куда вперед миграция удаляет функцию, приводящую к данным, отбрасываемым от базы данных. По очевидным причинам, обратная миграция не может реанимировать отброшенные данные. , Хотя, в таких случаях, можно было рекомендовать иметь вперед, миграция автоматически сохраняет данные или имеет в наличии их в возможности отката как альтернатива прямому отказу (сохраните к yml
, копируйте/перемещайте в специальную таблицу, и т.д.), Вы не имеете к, поскольку время, требуемое протестировать такую автоматизированную процедуру, могло превысить время, требуемое восстановить данные вручную (должен потребность возникать.) , Но даже в таких случаях, вместо того, чтобы просто перестать работать , можно всегда делать обратную миграцию условно и временно сбой, ожидающий некоторое пользовательское действие (т.е. тестировать на существование некоторой необходимой таблицы, которая должна быть восстановлена вручную; при пропавших без вести вывод "Я перестал работать, потому что я не могу воссоздать таблицу XYZ
от небытия; вручную таблица XYZ
восстановления от резервного копирования тогда выполняет меня снова, и я не приведу Вас к сбою!")
Для чувствования себя подобно Вам нужна необратимая миграция, вероятно, знак, у Вас есть большие проблемы при смутном очертании. Возможно, некоторые специфические особенности помогли бы?
Что касается Вашего второго вопроса: Я всегда прилагаю 'усилия' для записи реверса миграций. Конечно, я на самом деле не пишу эти .down
, TextMate вставляет его автоматически при создании .up
.
В производственном сценарии, необходимо всегда прилагать усилие, чтобы записать и протестировать обратимую миграцию в возможности, что Вы проходите его в производстве, затем обнаруживаете ошибку, которая вынуждает Вас откатывать (код и схема) к некоторому предыдущему пересмотру (ожидающий некоторая нетривиальная фиксация - и в других отношениях неприменимая производственная система.)
Наличие обратимой миграции хорошо для разработки и подготовки, но принятие хорошо протестированного кода, должно быть чрезвычайно редко, чтобы Вы когда-либо хотели бы мигрировать вниз в производстве. Я встраиваю в свои миграции автоматический IrreversibleMigration в производственном режиме. Если бы я действительно должен был обратить изменение, то я мог бы использовать другого миграция или удалить исключение. Это кажется поверхностным все же. Любая ошибка, которая вызвала бы сценарий это страшное, является знаком, что процесс QA серьезно завинчен.
IIRC, у Вас будет IrreversibleMigration при изменении типа данных в миграции.
If you are destroying data, you can make a backup of it first. e.g.
def self.up
# create a backup table before destroying data
execute %Q[create table backup_users select * from users]
remove_column :users, :timezone
end
def self.down
add_column :users, :timezone, :string
execute %Q[update users U left join backup_users B on (B.id=U.id) set U.timezone = B.timezone]
execute %Q[drop table backup_users]
end