2013-10-29 4 views
0

좋아, 정말 이상한 문제입니다.레일은 옵션 해시를 문자열로 변환합니다.

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 

: 여기

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 

라이브러리 코드의 샘플입니다 : 내 레일 마이그레이션이 같은 코드를 작성할 수 있도록 내가 액티브 :: 마이그레이션을 확장하는 라이브러리를 작성하려고 해요

== TestEnterprise: migrating ================================================= 
-- enterprise_mti_up({:superclass_table=>"test_superclasses", :subclass_tables=>["test_subclass_ones", "test_subclass_twos"]}) 
    -> 0.0005s 
== TestEnterprise: migrated (0.0007s) ======================================== 

그러나 사실 레일에 일부 있기 때문에 데이터베이스가 변경되지 : 나는 어느 방향으로 마이그레이션을 실행하면 모든 가 작동 나타납니다 enterprise_mti_up 및 enterprise_mti_down에서 옵션 해시를 문자열로 변환하는 방법! 내가 해시를 조작하는 기능 중 하나를 변경하면, 다음과 같은 결과를 얻을 :

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는 마이그레이션 메소드의 첫 번째 인수로 문자열/심볼을 기대하기가 어렵다고 생각하게됩니다.

+1

수정 된 버전의'enterprise_mti_down'은'extract_options! '를 두 번 호출했기 때문에 깨졌습니다.'extract_options!'는'Array # pop'을 둘러싸고있는 매우 얇은 래퍼입니다. 즉, 나는 너와 똑같은 행동을하는 것이 아니다. –

+0

args.extract_options를 바꾸십시오! args.first에 의해 – carlosavoy

+0

좋은 캐치, @muistooshort. – earksiinni

답변

1

문제가 발생했는지 정확히 알 수는 없지만 문제는 해결되었습니다. 나는 또 다른 보석, acts_as_relation에서이 줄을 cribbed했다

ActiveRecord::ConnectionAdapters::SchemaStatements.send :include, ActiveRecord::EnterpriseMtiMigrations 

, 레일에 MTI 기능을 추가 : 나는 액티브 코드 내 모듈 (액티브 :: EnterpriseMtiMigrations)를 포함하는 다음 줄을 사용하고 있었다. 그러나 acts_as_relation에 의해 정의 된 이주 메소드는 나중에 문자열 인수와 옵션 해시를 취합니다. 이 패턴은 ActiveRecord :: ConnectionAdapters :: SchemaStatements의 거의 모든 메소드가 정의되는 방식과 일치합니다 (예 : "create_table table_name, opts_hash").

실제로 필자는 SchemaStatements 모듈에 내 메서드를 포함시킴으로써 위에서 설명한 패턴과 일치시키기 위해 첫 번째 인수를 문자열로 강제 설정합니다. 나는 다음에 위의 코드의 라인 교체 :

ActiveRecord::Migration.send :include, ActiveRecord::EnterpriseMtiMigrations 

을 이제 모든 (@muistooshort에 의해 제안 된 두 번째 extract_options! 등을 제거한 후) 작동합니다. 그림을 이동.

+0

이 특별한 경우에 대해서는 잘 모르겠지만 많은 것들이 String과 Symbols을 정규화하기 위해 (즉'm (s) '와'm (: s)'가 같은 방식으로 동작하도록 인수에'to_s'를 호출 할 것입니다). 나는 ActiveRecord의 뒤틀린 창문 깊숙한 곳에서 당신의 SchemaStatements 패치를 사용하고 있었다고 생각합니다. 'ActiveRecord :: Migration' (또는 필요한 경우 모듈을 수동으로 포함하는 것)으로 바로 패치하는 것이 나에게 훨씬 더 의미가 있습니다. 하루 만의 답변을 수락 할 수 있다는 것을 잊지 마십시오. –

관련 문제