Created
July 2, 2013 04:51
-
-
Save konk303/5906838 to your computer and use it in GitHub Desktop.
This file contains 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
# -*- coding: utf-8 -*- | |
module ActiveRecord | |
module ConnectionAdapters # :nodoc: | |
module DatabaseStatements | |
# == rake db:fixture:load のmonkey patch | |
# 既存のfixture yamlに下記の問題がある | |
# # 型的に不正な初期値を使用してる箇所がある (sql_mode TRADITIONAL では落ちる) | |
# # NOT NULL制約のあるカラムに値をセットしていない時がある (sql_mode TRADITIONAL では落ちる) | |
# # 日付・時間カラムに、システム最小日付(lws_time)が入らない | |
# ので、ActiveRecord::ConnectionAdapters::DatabaseStatements.insert_fixture | |
# を書き換え | |
# === 詳細 | |
# `conncection.executeで INSERT INTO を発行` | |
# ↓ | |
# modelをfactory.build (factoryがなければModel.new)して値代入 | |
# 最小日付セット後にattributesで INSERT INTO | |
# === FIXME | |
# 1レコードずつAR(更にFactoryGirl)をインスタンス化するので、遅い | |
# === original | |
# # Inserts the given fixture into the table. Overridden in adapters that require | |
# # something beyond a simple insert (eg. Oracle). | |
# def insert_fixture(fixture, table_name) | |
# columns = schema_cache.columns_hash(table_name) | |
# key_list = [] | |
# value_list = fixture.map do |name, value| | |
# key_list << quote_column_name(name) | |
# quote(value, columns[name]) | |
# end | |
# execute "INSERT INTO #{quote_table_name(table_name)} (#{key_list.join(', ')}) VALUES (#{value_list.join(', ')})", 'Fixture Insert' | |
# end | |
def insert_fixture_with_model_instance(fixture, table_name) | |
puts "insert into #{table_name} id:#{fixture["id"]}" | |
instance = begin | |
FactoryGirl.build(table_name.singularize) | |
rescue | |
if table_name == 'm_origin_countries' | |
MOriginCountries.new | |
else | |
table_name.classify.constantize.new | |
end | |
end | |
fixture.each do |k, v| | |
instance.__send__("#{k}=", v) | |
end | |
instance.__send__(:set_zero_date) | |
transaction do | |
# == insert_fixtureをtransactionで囲む | |
# autocommit=0なmysql上で、establish_connectionを別実行してるmodelの | |
# fixtureが入らなかった。 | |
# 原因はActiveRecord::Baseのtransaction上で実行されているので | |
# model独自connectionにCOMMITが発行されていなかったから。 | |
# ActiveRecord::Fixtures.create_fixturesに修正を入れるべきだが、methodが大きく | |
# 書き換えずらいので、とりあえずの対処として1レコードごとのexecuteをtransactionで囲む。 | |
insert_fixture_without_model_instance(instance.attributes, table_name) | |
end | |
end | |
alias_method_chain :insert_fixture, :model_instance | |
end | |
end | |
end |
This file contains 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
# -*- coding: utf-8 -*- | |
module ActiveRecord | |
class Migrator | |
# == rake db:migrateのmonkey patch | |
# autocommit=0なmysql上で、rake db:migrateに問題がある | |
# -> 最後に実行されたmigrationがschema_migrationsに記録されない。 | |
# (migration自体は実行されるが、記録が残らない) | |
# 次回実行時に、前回の最後のmigrationを実行しようとして破綻する。 | |
# | |
# 原因: | |
# mysqlはddl_transaction非対応のため、 | |
# ActiveRecord::Base.connection.supports_ddl_transactions? はfalseにセットされ、 | |
# migrationはBEGIN/COMMIT抜きで実行される。 | |
# schemaの変更は自動的にコミットされるのでそれはOKなのだが、 | |
# schema_migrationへのupdate文もブロック内にあるため、 | |
# autocommit=0の環境では最後のinsertがcommitされない | |
# http://dev.mysql.com/doc/refman/5.1/ja/implicit-commit.html | |
# http://stackoverflow.com/questions/15146414/rails-mysql-autocommit-and-schema-migrations-table-bug | |
# | |
# 対策: | |
# ddl_transactionの部分はいじらず、 | |
# schema_migration変更部分をtransactionで囲む | |
# - ddl_transactionでないmigrationではtransactionが2重になるが、 | |
# activerecordが片方しか発行しないので問題ない | |
private | |
def record_version_state_after_migrating_with_transaction(version) | |
Base.transaction do | |
record_version_state_after_migrating_without_transaction(version) | |
end | |
end | |
alias_method_chain :record_version_state_after_migrating, :transaction | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment