ITコンサルの日常

ITコンサル会社に勤務する普通のITエンジニアの日常です。

CSVファイルでもDynamic Fixturesが使えるのか(結論: fixtures.rbにパッチを当てれば使える)

Class: FixturesのDynamic fixtures with ERbの節に、

In these cases, you can mix ERb in with your YAML or CSV fixtures to create a bunch of fixtures for load testing

とか書いてあるので、YAMLだけじゃなくて、CSVでもDynamic Fixturesが使えそうな雰囲気です。


まず、こんなCSVファイルを用意しました。

id,name
1,test
2,hoge
<% 10.times do |i| %>
<%= (i+3) %>,hoge<%= i %>
<% end %>

erbが埋め込まれているより前の部分までならば、正常にロードできます。
ただ、このままだと、

id,name
1,test
2,hoge

3,hoge0

4,hoge1

5,hoge2

6,hoge3

7,hoge4

8,hoge5

9,hoge6

10,hoge7

11,hoge8

12,hoge9

のようなCSVが出力されてしまい、このままFixturesに食わせると、

E:/jruby-1.1.4/lib/ruby/gems/1.8/gems/activerecord-2.1.1/lib/active_record/conne
ction_adapters/abstract/database_statements.rb:73:in `transaction': ActiveRecord
::ActiveRecordError: Syntax error: Encountered ")" at line 1, column 33.: INSERT
 INTO PEOPLE (id) VALUES () (ActiveRecord::StatementInvalid)
        from E:/jruby-1.1.4/lib/ruby/gems/1.8/gems/activerecord-2.1.1/lib/active
_record/fixtures.rb:518:in `create_fixtures'
        from E:/jruby-1.1.4/lib/ruby/gems/1.8/gems/activerecord-2.1.1/lib/active
_record/connection_adapters/abstract_adapter.rb:78:in `disable_referential_integ
rity'
        from E:/jruby-1.1.4/lib/ruby/gems/1.8/gems/activerecord-2.1.1/lib/active
_record/fixtures.rb:509:in `create_fixtures'
        from E:/jruby-1.1.4/lib/ruby/gems/1.8/gems/activerecord-2.1.1/lib/active
_record/base.rb:1267:in `silence'
        from E:/jruby-1.1.4/lib/ruby/gems/1.8/gems/activerecord-2.1.1/lib/active
_record/fixtures.rb:508:in `create_fixtures'
        from hoge.rb:12

のようなエラーとなってしまいます。


そこで、-%>の出番キタ!って感じです。
早速CSVを以下のように修正します。

id,name
1,test
2,hoge
<% 10.times do |i| -%>
<%= (i+3) %>,hoge<%= i %>
<% end -%>

が、これまたエラーになります。

E:/jruby-1.1.4/lib/ruby/1.8/erb.rb:743: (erb):5: , unexpected ';' (SyntaxError)

trim_modeの指定の問題のようです。


で、
lib/ruby/gems/1.8/gems/activerecord-2.1.1/lib/active_record/fixtures.rb
をみてみると、

    def erb_render(fixture_content)
      ERB.new(fixture_content).result
    end

trim_modeの指定無いじゃん。ってわけで、こんなパッチを当ててみる。

    def erb_render(fixture_content)
      #ERB.new(fixture_content).result
      ERB.new(fixture_content, nil, "-").result
    end

すると、無事動きました。