web-dev-qa-db-ja.com

複数値フィールドコレクションへの移行

この問題のコメント#222にあるパッチ( https://drupal.org/node/1175082#comment-7625869 )を使用して、データを複数値フィールドコレクションに移行しようとしています。

PrepareRow()でオブジェクトの配列を作成しますが、移行が完了してノードを確認すると、配列の最初の項目のみがフィールドコレクションに入力されており、後続の項目は追加されていません。重要なものが欠けていますか?

<?php
class IngredientsMigration extends BasicMigration {
  public function __construct($arguments) {
    parent::__construct($arguments);
    $this->description = t('Migrate recipe ingredients from the source database into field collections.');
    $this->dependencies = array('Recipe');

    $query = Database::getConnection('default', 'legacy')
      ->select('recipes', 'r')
      ->fields('r', array('id', 'ingredients'))
        ->condition('r.id', array(2), 'IN');

    $this->source = new MigrateSourceSQL($query);
    $this->destination = new MigrateDestinationFieldCollection(
      'field_collection_ingredients',
      array('Host_entity_type' => 'node')
    );

    $this->map = new MigrateSQLMap($this->machineName,
      array(
        'id' => array('type' => 'int',
          'length' => 11,
          'not null' => TRUE,
          'description' => 'Recipe ID',
          'alias' => 'r',
          ),
      ),
      MigrateDestinationFieldCollection::getKeySchema()
    );

    $this->addFieldMapping('Host_entity_id', 'id')
      ->sourceMigration('Recipe')
      ->issueNumber(16);
    $this->addFieldMapping('field_ingredient_text', 'ingredients')
      ->description(t('See prepareRow method'))
      ->issueNumber(16);

    $this->addUnmigratedDestinations(array(
      'path',
      )
    );
  }

  public function prepareRow($row) {
    // Always include this fragment at the beginning of every prepareRow()
    // implementation, so parent classes can ignore rows.
    if (parent::prepareRow($row) === FALSE) {
      return FALSE;
    }

    $ingredients_array = preg_split('/$\R?^/m', $row->ingredients);
    $row->ingredients = array();
    foreach ($ingredients_array as $ingredient) {
      $row->ingredients[] = $ingredient;
    }
    return TRUE;
  }
}
6
markdorison

移行前に実行するDrushコマンドを記述して、ソースデータベースから「材料」フィールドを取得し、それぞれが独自の行とデルタ列に解析された状態で新しいテーブルを作成して、順序を維持しました。次に、レシピテーブルではなく、このテーブルを指すように食材の移行を設定しました。

この移行のための私のDB接続は、次のようになりました。

$query = Database::getConnection('default', 'legacy')
  ->select('_recipe_ingredients', 'i')
    ->fields('i', array('id', 'recipe_id', 'ingredient'))
    ->orderBy('i.recipe_id')
    ->orderBy('i.delta');
1
markdorison

これを試すこともできます(この質問にも回答: フィールドコレクションへの移行 ):

もう1つのオプションは、completeクラスのMigrationメソッドを実装し、プログラムでフィールドコレクションにデータを入力することです。

次のコードは、単一のフィールドコレクションアイテムをノードに保存します。

public function complete($entity, $row) {

  // load the newly created node (just in case entity isn't fully populated).
  $node = node_load($entity->nid);

  // set the values of all field collection fields
  $values = array(
    'field_name' => 'FIELD_COLLECTION_ITEM_FIELD_NAME',
    'field1'     => array(LANGUAGE_NONE => array(array('value' => 'VALUE'))),
    'field3'     => array(LANGUAGE_NONE => array(array('value' => 'VALUE'))),
  );

  // create the field collection item entity
  $item = entity_create('field_collection_item', $values);

  // attach it to the node loaded above
  $item->setHostEntity('node', $node);

  // save the entity
  $item->save();
}

これを変更して、複数のフィールドコレクション項目をかなり簡単に保存できます。

public function complete($entity, $row) {

  // load the newly created node (just in case entity isn't fully populated).
  $node = node_load($entity->nid);

  // loop values to add as field collection items (assumes you have them in a $values array).
  foreach ($values as $key => $value) {

    // set the values of all field collection fields
    $values = array(
      'field_name' => 'FIELD_COLLECTION_ITEM_FIELD_NAME',
      'field1'     => array(LANGUAGE_NONE => array(array('value' => 'VALUE'))),
      'field3'     => array(LANGUAGE_NONE => array(array('value' => 'VALUE'))),
    );

    // create the field collection item entity
    $item = entity_create('field_collection_item', $values);

    // attach it to the node loaded above
    $item->setHostEntity('node', $node);

    // save the entity
    $item->save();
  }
}

[〜#〜]注[〜#〜]:フィールドコレクションアイテムにファイルを追加する場合、ファイルはロールバック時に削除されませんあなたはそれを明示的に行います。

1
Scott Joudry