gem activerecord-import の README を翻訳しました

# 概要
gem [activerecord-import](https://github.com/zdennis/activerecord-import) の [README](https://github.com/zdennis/activerecord-import/blob/master/README.markdown) を翻訳しました。

- 翻訳について
    - 翻訳サービス [Deepl](https://www.deepl.com/translator) と [Goole翻訳](https://translate.google.co.jp/) の訳文を参考にしている箇所があります。
    - 翻訳対象の[コミットハッシュ](https://github.com/zdennis/activerecord-import/commit/ef425b13e94d258f3c174dc54185fb113433095c)
    - 非公式の翻訳です。
    - 訳文がおかしい箇所があったら指摘をもらえると幸いです。

- ライセンスについて
    - [activerecord-import のライセンス](https://github.com/zdennis/activerecord-import/blob/master/LICENSE)と同様のライセンスに従います。

# Activerecord-Import

Activerecord-Import は ActiveRecord を使用してデータをバルクインサートするためのライブラリです。

このライブラリの主要な機能の1つは、下記の activerecord の関連付けで N+1 インサート問題を回避しつつ必要最低限の SQL インサート文を生成することです。具体例で説明していきます。下記のスキーマがあるとします。

- 出版社は複数の本を持っている
- 本は複数のレビューを持っている

そしてあなたは、本1つごとに3つのレビューがあり、出版社1つごとに1万の本を持つ100の新しい出版社をバルクインサートしたいと思っています。このライブラリは関連付けに従って、3つのみの SQL インサート文を生成するだけです。1つは出版社、1つは本、1つはレビューのインサート文です。

対照的に、標準的な ActiveRecord は出版社の100個のインサート文を生成し、それから各出版社のレコードを確認してすべての本を保存します。
100 * 10,000 = 1,000,000 SQL インサート文
そしてそれからレビューを保存します。
100 * 10,000 * 3 = 3M SQL インサート文

これは 4M対3の SQL インサート文となります。これにより非常に大きなパフォーマンスの改善となります。今回の例では、18時間のバッチ処理時間が2時間未満になります。

この gem は下記の高水準の機能を提供します。

* ローカラムと値の配列を伴った動作（最も速い）
* モデルオブジェクトを伴った動作（より速い）
* バリデーションの実行（速い）
* duplicate key updates の実行（MySQL, SQLite 3.24.0+, Postgres 9.5+を必要とします）

## 目次


- [例](#%E4%BE%8B)
  - [導入](#%E5%B0%8E%E5%85%A5)
  - [カラムと配列](#%E3%82%AB%E3%83%A9%E3%83%A0%E3%81%A8%E9%85%8D%E5%88%97)
  - [ハッシュ](#%E3%83%8F%E3%83%83%E3%82%B7%E3%83%A5)
  - [ハッシュと明示的なカラム名を使用したインポート](#%E3%83%8F%E3%83%83%E3%82%B7%E3%83%A5%E3%81%A8%E6%98%8E%E7%A4%BA%E7%9A%84%E3%81%AA%E3%82%AB%E3%83%A9%E3%83%A0%E5%90%8D%E3%82%92%E4%BD%BF%E7%94%A8%E3%81%97%E3%81%9F%E3%82%A4%E3%83%B3%E3%83%9D%E3%83%BC%E3%83%88)
  - [ActiveRecord モデル](#activerecord-%E3%83%A2%E3%83%87%E3%83%AB)
  - [バッチ](#%E3%83%90%E3%83%83%E3%83%81)
  - [再帰](#%E5%86%8D%E5%B8%B0)
- [オプション](#%E3%82%AA%E3%83%97%E3%82%B7%E3%83%A7%E3%83%B3)
  - [Duplicate Key Ignore](#duplicate-key-ignore)
  - [Duplicate Key Update](#duplicate-key-update)
- [返り値](#%E8%BF%94%E3%82%8A%E5%80%A4)
- [カウンターキャッシュ](#%E3%82%AB%E3%82%A6%E3%83%B3%E3%82%BF%E3%83%BC%E3%82%AD%E3%83%A3%E3%83%83%E3%82%B7%E3%83%A5)
- [ActiveRecord のタイムスタンプ](#activerecord-%E3%81%AE%E3%82%BF%E3%82%A4%E3%83%A0%E3%82%B9%E3%82%BF%E3%83%B3%E3%83%97)
- [コールバック](#%E3%82%B3%E3%83%BC%E3%83%AB%E3%83%90%E3%83%83%E3%82%AF)
- [サポートされているアダプタ](#%E3%82%B5%E3%83%9D%E3%83%BC%E3%83%88%E3%81%95%E3%82%8C%E3%81%A6%E3%81%84%E3%82%8B%E3%82%A2%E3%83%80%E3%83%97%E3%82%BF)
- [追加のアダプタ](#%E8%BF%BD%E5%8A%A0%E3%81%AE%E3%82%A2%E3%83%80%E3%83%97%E3%82%BF)
- [Requiring](#requiring)
  - [Bundler による自動読み込み](#bundler-%E3%81%AB%E3%82%88%E3%82%8B%E8%87%AA%E5%8B%95%E8%AA%AD%E3%81%BF%E8%BE%BC%E3%81%BF)
  - [手動読み込み](#%E6%89%8B%E5%8B%95%E8%AA%AD%E3%81%BF%E8%BE%BC%E3%81%BF)
- [ロードパスの仕組み](#%E3%83%AD%E3%83%BC%E3%83%89%E3%83%91%E3%82%B9%E3%81%AE%E4%BB%95%E7%B5%84%E3%81%BF)
- [他の gem との衝突](#%E4%BB%96%E3%81%AE-gem-%E3%81%A8%E3%81%AE%E8%A1%9D%E7%AA%81)
- [詳細情報](#%E8%A9%B3%E7%B4%B0%E6%83%85%E5%A0%B1)
- [Contributing](#contributing)
  - [Running Tests](#running-tests)
- [Issue Triage *](#issue-triage-)



### 例

#### 導入

この gem は `import` メソッドを ActiveRecord クラスに追加します。
あるいは `elasticsearch-model`のような gem との互換性のために `bulk_import` メソッドを追加します。[Conflicts With Other Gems](#conflicts-with-other-gems)をご覧ください

`activerecord-import` を使用しない場合、下記のような記述をするでしょう。

```ruby
10.times do |i|
  Book.create! name: "book #{i}"
end
```

このコードは10回の SQL を呼び出すことになります。`activerecord-import` を使用すると、代わりに下記のように書くことができます。

```ruby
books = []
10.times do |i|
  books << Book.new(name: "book #{i}")
end
Book.import books    # あるいは import! を使用してください
```

1回の SQL 呼び出しのみが起こります。

#### カラムと配列

`import` メソッドはカラム名（string or symbols）の配列と配列の配列を受けることができます。各子配列は個々のレコードとカラムと同順の値のリストをあらわしています。これは最も速いインポートの仕組みであり、もっとも原始的な仕組みでもあります。

```ruby
columns = [ :title, :author ]
values = [ ['Book1', 'George Orwell'], ['Book2', 'Bob Jones'] ]

# モデルのバリデーションなしのインポート
Book.import columns, values, validate: false

# モデルのバリデーション有りのインポート
Book.import columns, values, validate: true

# 指定がない場合、:validate はデフォルトで true になる
Book.import columns, values
```

#### ハッシュ

`import` メソッドはハッシュの配列を受けることができます。キー名はデータベースのカラム名に対応しています。

```ruby
values = [{ title: 'Book1', author: 'George Orwell' }, { title: 'Book2', author: 'Bob Jones'}]

# モデルのバリデーションなしのインポート
Book.import values, validate: false

# モデルのバリデーション有りのインポート
Book.import values, validate: true

# 指定がない場合、:validate はデフォルトで true になる
Book.import values
```

#### ハッシュと明示的なカラム名を使用したインポート

`import` メソッドはカラム名の配列とハッシュオブジェクトの配列を受け取ることができます。カラム名はどのデータフィールドがインポートされるかを決めるために使用されます。下記の例では `title` フィールドのみインポートされます。

```ruby
books = [
  { title: "Book 1", author: "George Orwell" },
  { title: "Book 2", author: "Bob Jones" }
]
columns = [ :title ]

# バリデーションなし
Book.import columns, books, validate: false

# バリデーション有り
Book.import columns, books, validate: true

# 指定がない場合、:validate はデフォルトで true になる
Book.import columns, books

# books テーブルの結果
# title  | author
#--------|--------
# Book 1 | NULL
# Book 2 | NULL

```

配列の各ハッシュのカラムが一致している場合のみ、ハッシュの使用は動作します。そうでない場合は例外が発生します。2つの回避策があります。1つ目は、ActiveRecord オブジェクトの配列をインスタンス化した配列を使用し、それを `import` メソッドに渡す方法です。2つ目は、配列が一致したカラムを持つ複数の配列に分割し、別々に `import` メソッドに渡す方法です。

詳細は https://github.com/zdennis/activerecord-import/issues/507 をご覧ください。

```ruby
arr = [
  { bar: 'abc' },
  { baz: 'xyz' },
  { bar: '123', baz: '456' }
]

# 例外が発生する
Foo.import arr

# better
arr.map! { |args| Foo.new(args) }
Foo.import arr

# better
arr.group_by(&:keys).each_value do |v|
 Foo.import v
end
```

#### ActiveRecord モデル

`import` メソッドはモデルの配列を受け取ることができます。モデルの利用可能なカラムを探すことで各モデルから属性を取得します。

```ruby
books = [
  Book.new(title: "Book 1", author: "George Orwell"),
  Book.new(title: "Book 2", author: "Bob Jones")
]

# バリデーションなし
Book.import books, validate: false

# バリデーション有り
Book.import books, validate: true

# 指定がない場合、:validate はデフォルトで true になる
Book.import books
```

`import` メソッドはカラム名の配列とモデルの配列を受け取ることができます。カラム名はどのデータフィールドがインポートされるかを決めるために使用されます。下記の例では `title` フィールドのみインポートされます。

```ruby
books = [
  Book.new(title: "Book 1", author: "George Orwell"),
  Book.new(title: "Book 2", author: "Bob Jones")
]
columns = [ :title ]

# バリデーションなし
Book.import columns, books, validate: false

# バリデーション有り
Book.import columns, books, validate: true

# 指定がない場合、:validate はデフォルトで true になる
Book.import columns, books

# books テーブルの結果
# title  | author
#--------|--------
# Book 1 | NULL
# Book 2 | NULL

```

#### バッチ

`import` メソッドはインサート文ごとにインサートする行数を制御するために、`batch_size` オプションを受け取ることができます。デフォルトはインサートされる全レコードになっているので、1つのインサート文が発行されます。

```ruby
books = [
  Book.new(title: "Book 1", author: "George Orwell"),
  Book.new(title: "Book 2", author: "Bob Jones"),
  Book.new(title: "Book 1", author: "John Doe"),
  Book.new(title: "Book 2", author: "Richard Wright")
]
columns = [ :title ]

# 4レコードで2つのインサート文が発行される
Book.import columns, books, batch_size: 2
```

#### 再帰

注意: この機能は PostgreSQL のみで動作します。

本は複数のレビューを持つと仮定します。

```ruby
books = []
10.times do |i|
  book = Book.new(name: "book #{i}")
  book.reviews.build(title: "Excellent")
  books << book
end
Book.import books, recursive: true
```

### オプション

Key                     | Options               | Default            | Description
----------------------- | --------------------- | ------------------ | -----------
:validate               | `true`/`false`        | `true`             | `ActiveRecord` バリデーション（ユニークネスはスキップされる）の実行の有無。`import!` メソッドの使用時にはこのオプションは常に true になります。
:validate_uniqueness    | `true`/`false`        | `false`            | ユニークネスバリデーションの実行の有無。潜在的な落とし穴がある可能性があります。バージョン `>= v0.27.0` を必要とするので注意して使用してください。
:validate_with_context  | `Symbol`              |`:create`/`:update` | 各モデルに ActiveModel バリデーションコンテキストを渡すことを許可します。デフォルは、新レコードに対しては `:create`、既存レコードに対しては `:update` です。
:on_duplicate_key_ignore| `true`/`false`        | `false`            | 重複したキーのレコードをスキップすることを許可します。詳細は[こちら](https://github.com/zdennis/activerecord-import/#duplicate-key-ignore)をご覧ください。
:ignore                 | `true`/`false`        | `false`            | :on_duplicate_key_ignore のエイリアスです。
:on_duplicate_key_update| :all, `Array`, `Hash` | N/A                | upsert を許可します。詳細は[こちら](https://github.com/zdennis/activerecord-import/#duplicate-key-update)をご覧ください。
:synchronize            | `Array`               | N/A                | ActiveRecord のインスタンスの配列が入ります。メモリ上の既存のインスタンスにインポートによる更新をシンクロします。
:timestamps             | `true`/`false`        | `true`             | インポートするレコードにおけるタイムスタンプの有効・無効。
:recursive              | `true`/`false`        | `false`            | has_many/has_one の関連付けをインポートします（PostgreSQLのみ）。
:batch_size             | `Integer`             | total # レコードの | インポートごとにインサートするレコードの最大数。
:raise_error            | `true`/`false`        | `false`            | 最初の無効なレコードで例外を起こします。インポートの返り値でオブジェクトは返しません。`import!` メソッドのショートカットです。
:all_or_none            | `true`/`false`        | `false`            | ある1つのレコードでバリデーションエラーが起こったときにすべてのインポートを無効にするかどうか。

#### Duplicate Key Ignore

[MySQL](http://dev.mysql.com/doc/refman/5.0/en/insert-on-duplicate.html), [SQLite](https://www.sqlite.org/lang_insert.html) と [PostgreSQL](https://www.postgresql.org/docs/current/static/sql-insert.html#SQL-ON-CONFLICT) (9.5+) は主キーあるいはユニークキー制約に引っかかったときにそのレコードをスキップする `on_duplicate_key_ignore` をサポートしています。

`on_duplicate_key_ignore` は Postgres 9.5+ では `ON CONFLICT DO NOTHING`、MySQL では `INSERT IGNORE`、SQLite では `INSERT OR IGNORE` を追加します。再帰的インポートではこのオプションは利用できません。データベースアダプタはインポートされるオブジェクトの主キーの設定を標準的にサポートするため、このオプションはそれを妨げます。

```ruby
book = Book.create! title: "Book1", author: "George Orwell"
book.title = "Updated Book Title"
book.author = "Bob Barker"

Book.import [book], on_duplicate_key_ignore: true

book.reload.title  # => "Book1"     (変化なし)
book.reload.author # => "George Orwell" (変化なし)
```

[PostgreSQL のインポート](https://github.com/zdennis/activerecord-import/wiki#recursive-example-postgresql-only)において `:recursive` オプションが利用可能なとき、`:on_duplicate_key_ignore` オプションは無視されます。

#### Duplicate Key Update

MySQL, PostgreSQL (9.5+), SQLite (3.24.0+) は主キーあるいはユニークキー制約に該当したときのみ更新されるフィールドを指定する `on duplicate key update`（"upsert"としても知られています） をサポートします。

MySQL と PostgreSQL では一つの大きな差異があります。それは MySQL は発生したコンフリクトすべてを処理しますが、PostgreSQL はコンフリクトが発生するカラムが指定されたものであることを必要とします。SQLite は PostgreSQL の動作に倣います。

下記は MySQL の `ON DUPLICATE KEY UPDATE`、Postgres/SQLite の `ON CONFLICT DO UPDATE` を使用した upsert の記述です。

基本的な更新

```ruby
book = Book.create! title: "Book1", author: "George Orwell"
book.title = "Updated Book Title"
book.author = "Bob Barker"

# MySQL バージョン
Book.import [book], on_duplicate_key_update: [:title]

# PostgreSQL バージョン
Book.import [book], on_duplicate_key_update: {conflict_target: [:id], columns: [:title]}

# PostgreSQL 省略バージョン (conflict_target は主キーである必要があります)
Book.import [book], on_duplicate_key_update: [:title]

book.reload.title  # => "Updated Book Title" (変更)
book.reload.author # => "George Orwell"      (変更なし)
```

別カラムの値を使用

```ruby
book = Book.create! title: "Book1", author: "George Orwell"
book.title = "Updated Book Title"

# MySQL バージョン
Book.import [book], on_duplicate_key_update: {author: :title}

# PostgreSQL バージョン (非省略バージョン)
Book.import [book], on_duplicate_key_update: {
  conflict_target: [:id], columns: {author: :title}
}

book.reload.title  # => "Book1"              (変更なし)
book.reload.author # => "Updated Book Title" (変更)
```

カスタム SQL を使用

```ruby
book = Book.create! title: "Book1", author: "George Orwell"
book.author = "Bob Barker"

# MySQL バージョン
Book.import [book], on_duplicate_key_update: "author = values(author)"

# PostgreSQL バージョン
Book.import [book], on_duplicate_key_update: {
  conflict_target: [:id], columns: "author = excluded.author"
}

# PostgreSQL 省略バージョン(conflict_target は主キーである必要があります)
Book.import [book], on_duplicate_key_update: "author = excluded.author"

book.reload.title  # => "Book1"      (変更なし)
book.reload.author # => "Bob Barker" (変更)
```

制約を使用した PostgreSQL

```ruby
book = Book.create! title: "Book1", author: "George Orwell", edition: 3, published_at: nil
book.published_at = Time.now

# マイグレーション
execute <<-SQL
      ALTER TABLE books
        ADD CONSTRAINT for_upsert UNIQUE (title, author, edition);
    SQL

# PostgreSQL バージョン
Book.import [book], on_duplicate_key_update: {constraint_name: :for_upsert, columns: [:published_at]}


book.reload.title  # => "Book1"          (変更なし)
book.reload.author # => "George Orwell"      (変更なし)
book.reload.edition # => 3               (変更なし)
book.reload.published_at # => 2017-10-09 (変更)
```

```ruby
Book.import books, validate_uniqueness: true
```

### 返り値

`import` メソッドは `failed_instances` と `num_inserts` に応答する `Result` オブジェクトを返却します。加えて Postgres の場合は、`ids` と `results` という2つの配列も利用可能です。

```ruby
articles = [
  Article.new(author_id: 1, title: 'First Article', content: 'This is the first article'),
  Article.new(author_id: 2, title: 'Second Article', content: ''),
  Article.new(author_id: 3, content: '')
]

demo = Article.import(articles, returning: :title) # => #<struct ActiveRecord::Import::Result

demo.failed_instances
=> [#<Article id: 3, author_id: 3, title: nil, content: "", created_at: nil, updated_at: nil>]

demo.num_inserts
=> 1,

demo.ids
=> ["1", "2"] # Postgres のとき
=> [] # 他 DB のとき

demo.results
=> ["First Article", "Second Article"] # Postgres のとき
=> [] # 他 DB のとき
```

### カウンターキャッシュ

`import` を実行したとき、`activerecord-import` はカウンターキャッシュを自動的に更新しません。それらのカラムを更新するには、下記のどちらかを行う必要があります。

* `import` メソッドに渡されるオブジェクトの引数としてカウンターキャッシュカラムに値を与える
* レコードのインポート後にカウンターキャッシュカラムを手動で更新する

### ActiveRecord のタイムスタンプ

ActiveRecord に慣れている場合、created_at, created_on, updated_at, updated_on などのタイムスタンプカラムがに馴染みがあると思います。データをインポートするとき、このタイムスタンプフィールドは期待通りに動作し、タイムスタンプカラムに値がセットされます。

これらのカラムに値を指定したいときは、`timestamps: false` オプションを使用してください。

しかしながら、特定のレコードにおいて `:created_at` のみを設定することもできます。この場合、`timestamps: true` を使用するにも関わらず、フィールドが `nil` のレコードにおいて `:created_at` のみが更新されます。`recursive: true` オプションを使用するときにも関連付けられたレコードに対して同じルールが適用されます。

カスタムタイムゾーンを使用している場合は、 `ActiveRecord::Base.default_timezone` が設定されているとき（ほぼすべての Rails アプリがこの設定である）と同様にインポートを行う際にそれらも考慮されます。

### コールバック

import メソッドを呼び出したとき、レコードの [作成](http://guides.rubyonrails.org/active_record_callbacks.html#creating-an-object), [更新](http://guides.rubyonrails.org/active_record_callbacks.html#updating-an-object), [削除](http://guides.rubyonrails.org/active_record_callbacks.html#destroying-an-object)（`before_validation` と `after_validation` ではなく）に関連する ActiveRecord のコールバックは呼び出されません。import メソッドでは大量のデータ行のインポートが行われ、かつ、メモリ内の ActiveRecord オブジェクトにアクセスする必要が必ずしもないからです。

メモリ内に ActiveRecord オブジェクトのコレクションを持っている場合は、下記のように記述することができます。

```ruby
books.each do |book|
  book.run_callbacks(:save) { false }
  book.run_callbacks(:create) { false }
end
Book.import(books)
```

上記のコードは各アイテムで before_create と before_save コールバックを実行します。引数 `false` は after_save コールバックが実行されないようにするのに必要ですが、これはバルクインポートには意味をなしません。上記のコードでは before_create と before_save コールバックはバリデーションコールバックの前に実行されることに注意してください。

これが課題になる場合は、別の方法として、モデルをループさせてバリデーションを行い、バリデーションが問題ないモデルのみ run_callbacks を実行してインポートすることもできます。

```ruby
valid_books = []
invalid_books = []

books.each do |book|
  if book.valid?
    valid_books << book
  else
    invalid_books << book
  end
end

valid_books.each do |book|
  book.run_callbacks(:save) { false }
  book.run_callbacks(:create) { false }
end

Book.import valid_books, validate: false
```

### サポートされているアダプタ

下記のデータベースアダプタが現在サポートされています。

* MySQL - 中心的な重要機能に加えて duplicate key update もサポートしています（activerecord-import 0.1.0 以上に含まれています）
* MySQL2 - 中心的な重要機能に加えて duplicate key update もサポートしています（activerecord-import 0.2.0 以上に含まれています）
* PostgreSQL - 中心的な重要機能をサポートしています（activerecord-import 0.1.0 以上に含まれています）
* SQLite3 - 中心的な重要機能をサポートしています（activerecord-import 0.1.0 以上に含まれています）
* Oracle - DML トリガーを通して中心的な重要機能をサポートしています（外部 gem [activerecord-import-oracle_enhanced](https://github.com/keeguon/activerecord-import-oracle_enhanced)で利用可能です）
* SQL Server - 中心的な重要機能をサポートしています（外部 gem [activerecord-import-sqlserver](https://github.com/keeguon/activerecord-import-sqlserver)で利用可能です）

使用しているアダプタがリストにないときは、README に記載されているように外部 gem を作成することを考慮に入れることをお願いします。もし外部 gem を作成した場合は、wiki を更新して新しいアダプタのリポジトリへのリンクを含めてください。

使用しているアダプタがどの機能をサポートしているかを知るためには、下記のモデルクラスのメソッドを使用してください。
* `supports_import?(*args)`
* `supports_on_duplicate_key_update?`
* `supports_setting_primary_key_of_imported_objects?`

### 追加のアダプタ

activerecord-import（それに続いて activerecord） によって動的に読み込まれるアダプタのために、命名規約の仕組みに一致するアダプタを提供することによって、追加のアダプタは外部 gem によって activerecord-import に与えられます。このことはロードパスにフォルダを与えることを必要とします。ロードパスは activerecord-import の命名規約に従い、activerecord-import が動的にファイルを読み込めるようにします。

`ActiveRecord::Import.require_adapter("fake_name")` が呼び出されるとき、下記を require してください。

```ruby
require 'activerecord-import/active_record/adapters/fake_name_adapter'
```

これによって、外部 gem が activerecord-import gem の中核に何らかのファイル・コードを追加することなくアダプタを動的に追加できるようになります。

### Requiring

注意: これらの説明は 0.2.0 以上のバージョンを使用しているときのみ動作します。

#### Bundler による自動読み込み

Rails を使用している、あるいは Bundler によって依存関係をオートロードしている場合は、下記のように `Gemfile` に gem を追加するだけです。

```ruby
gem 'activerecord-import'
```

#### 手動読み込み

何らかの理由で、手動で activerecord-import を読み込みたい場合があると思います。
その際はまず引数 `require: false` を追加してください。

```ruby
gem 'activerecord-import', require: false
```

これにより、必要なファイル内で必要な部分だけ activerecord-import を読み込めるようになります。
Rails 内で手動読み込みを行い、ActiveRecord がデータベース接続をしている場合は（コントローラー内のように）、特別な初期化処理を行う必要があります。

```ruby
require 'activerecord-import/base'
# 適切なデータベースアダプタを読み込んでください（postgresql, mysql2, sqlite3 など）
require 'activerecord-import/active_record/adapters/postgresql_adapter'
```

gem の依存関係がオートロードではなく、スクリプトがデータベースコネクションを作成している場合は、単純に ActiveRecord が読み込まれたあとに activerecord-import を require してください。

```ruby
require 'active_record'
require 'activerecord-import'
```

### ロードパスの仕組み
rubygems がどのようにコードを読み込んでいるかを理解するためには、下記を参照してください。

  http://guides.rubygems.org/patterns/#loading_code

active_record が動的にアダプタを読み込む例がこちらです。
  https://github.com/rails/rails/blob/master/activerecord/lib/active_record/connection_adapters/connection_specification.rb

まとめると、gem が読み込まれたとき、rubygems はその gem の `lib` フォルダをグローバルロードパスの `$LOAD_PATH` に追加します。それによって、すべての `require` の検索がロードパス上の全フォルダを探索しなくてすみます。`require` が実行されたとき、`$LOAD_PATH` の各フォルダはファイル/フォルダの参照のために確認されます。これによって、gem（activerecord-import のような）は `$LOAD_PATH` に activerecord-import フォルダ（あるいはネームスペース）を追加できるように定義できるようになり、require が実行されたときに、activerecord-import によって提供されるアダプタを発見できるようになります。

もし gem（潜在的に `activerecord-import-fake_name` と呼ばれる） に `fake_name` アダプタが必要になった場合、フォルダ構造は下記のようになります。

```bash
activerecord-import-fake_name/
|-- activerecord-import-fake_name.gemspec
|-- lib
|   |-- activerecord-import-fake_name.rb
|   |-- activerecord-import-fake_name
|   |   |-- version.rb
|   |-- activerecord-import
|   |   |-- active_record
|   |   |   |-- adapters
|   |   |       |-- fake_name_adapter.rb
```

rubygems　が `lib` フォルダをロードパスに追加したとき、`$LOAD_PATH` 内のパスの下で ruby ファイルの探索プロセスを通して起動するので、`require` は `activerecord-import/active_record/adapters/fake_name_adapter` を探します。

### 他の gem との衝突

Activerecord-Import は `ActiveRecord::Base` に `.import` メソッドを追加します。`elasticsearch-rails` のように同じ名前のメソッドを追加する他の gem も存在します。このような衝突のために、代わりに使用可能な `.bulk_import` というエイリアスメソッドが存在します。

`apartment` gem を使用している場合、モデルの `sequence_name` のキャッシュに関わって `apartment`,`activerecord-import`,`activerecord` 間に奇妙な3重の相互作用があります。モデル内でこの値を明確に設定することで、対応することができます。

```ruby
class Post < ActiveRecord::Base
  self.sequence_name = "posts_seq"
end
```

この問題に対応する別のやり方として、モデルで `.reset_sequence_name` を呼び出すこともできます。

```ruby
schemas.all.each do |schema|
  Apartment::Tenant.switch! schema.name
  ActiveRecord::Base.transaction do
    Post.reset_sequence_name

    Post.import posts
  end
end
```

詳細な議論は https://github.com/zdennis/activerecord-import/issues/233 をご覧ください。

### 詳細情報

Activerecord-Import の詳細な情報については、下記の wiki を参照してください。
https://github.com/zdennis/activerecord-import/wiki

新しい情報を記述するときは、 wiki の代わりに README に追加してください。
それについての議論は下記をご覧ください。
https://github.com/zdennis/activerecord-import/issues/397 for discussion.

### Contributing

#### Running Tests

The first thing you need to do is set up your database(s):

* copy `test/database.yml.sample` to `test/database.yml`
* modify `test/database.yml` for your database settings
* create databases as needed

After that, you can run the tests. They run against multiple tests and ActiveRecord versions.

This is one example of how to run the tests:

```ruby
rm Gemfile.lock
AR_VERSION=4.2 bundle install
AR_VERSION=4.2 bundle exec rake test:postgresql test:sqlite3 test:mysql2
```

Once you have pushed up your changes, you can find your CI results [here](https://travis-ci.org/zdennis/activerecord-import/).

## Issue Triage

You can triage issues which may include reproducing bug reports or asking for vital information, such as version numbers or reproduction instructions. If you would like to start triaging issues, one easy way to get started is to [subscribe to activerecord-import on CodeTriage](https://www.codetriage.com/zdennis/activerecord-import).

# License

This is licensed under the ruby license.

# Author

Zach Dennis (zach.dennis@gmail.com)