わかりました、これは本当に奇妙な問題です。Rails マイグレーションで次のようなコードを記述できるように、ActiveRecord::Migrations を拡張するライブラリを作成しようとしています。
class TestEnterprise < ActiveRecord::Migration
def up
enterprise_mti_up superclass_table: 'test_superclasses', subclass_tables: ['test_subclass_ones', 'test_subclass_twos']
end
def down
enterprise_mti_down superclass_table: 'test_superclasses', subclass_tables: ['test_subclass_ones', 'test_subclass_twos']
end
end
ライブラリ コードのサンプルを次に示します。
def enterprise_mti_up(*args)
enterprise_mti args.extract_options!, direction: :up
end
def enterprise_mti_down(*args)
enterprise_mti args.extract_options!, direction: :down
end
いずれかの方向で移行を実行すると、すべてが機能しているように見えます。
== TestEnterprise: migrating =================================================
-- enterprise_mti_up({:superclass_table=>"test_superclasses", :subclass_tables=>["test_subclass_ones", "test_subclass_twos"]})
-> 0.0005s
== TestEnterprise: migrated (0.0007s) ========================================
しかし、データベースは変更されていません。実際、Rails は、enterprise_mti_up と enterprise_mti_down からのオプション ハッシュを何らかの方法で文字列に変換しているからです。関数の 1 つを変更してハッシュを操作すると、次の結果が得られます。
def enterprise_mti_down(*args)
opts = args.extract_options!
puts "opts: #{opts}"
puts "opts[:superclass_table]: #{opts[:superclass_table]}"
puts "args: #{args}"
puts "args.last.class: #{args.last.class}"
enterprise_mti args.extract_options!, direction: :down
end
...
== TestEnterprise: reverting =================================================
-- enterprise_mti_down({:superclass_table=>"test_superclasses", :subclass_tables=>["test_subclass_ones", "test_subclass_twos"]})
opts: {}
opts[:superclass_table]:
args: ["{:superclass_table=>\"test_superclasses\", :subclass_tables=>[\"test_subclass_ones\", \"test_subclass_twos\"]}"]
args.last.class: String
-> 0.0002s
== TestEnterprise: reverted (0.0005s) ========================================
ハッシュが文字列に変換される理由と、ハッシュをメソッドに渡す方法を知っている人はいますか? ありがとう!
注:私のテストでは、オプション ハッシュの前に最初の引数として文字列を渡すと、すべてが想定どおりに機能することがわかりました。しかし、ハッシュの前に引数を持つ必要はありません。これにより、Rails は移行メソッドの最初の引数として文字列/シンボルを期待するように配線されているのではないかと思います。