web-dev-qa-db-ja.com

重複する分類用語が作成されないようにルールを修正するにはどうすればよいですか?

これは、 2つのフィールドの用語を組み合わせて新しい用語を作成し、それを3番目のフィールドに格納するルールを作成する方法 での私の質問のフォローアップですか? )。

次の例に示すように、ノードが表示されるたびに分類用語が重複して作成されるのを防ぐにはどうすればよいですか。

enter image description here

助言がありますか?

3
LIUJIAHUI

パート1-実際の課題について

私は、関連する質問の承認された回答のルールに似た(等しい?)ルールを使用していると想定しています。

{ "rules_improved_combination_of_taxonomy_terms" : {
    "LABEL" : "Improved combination of taxonomy terms",
    "PLUGIN" : "reaction rule",
    "OWNER" : "rules",
    "REQUIRES" : [ "rules" ],
    "ON" : { "node_view--article" : { "bundle" : "article" } },
    "DO" : [
      { "drupal_message" : { "message" : "[node:field-a][node:field-b]" } },
      { "variable_add" : {
          "USING" : { "type" : "text", "value" : "[node:field-a][node:field-b]" },
          "PROVIDE" : { "variable_added" : { "variable_added" : "Added variable" } }
        }
      },
      { "entity_create" : {
          "USING" : {
            "type" : "taxonomy_term",
            "param_name" : "[variable-added:value]",
            "param_vocabulary" : "tags"
          },
          "PROVIDE" : { "entity_created" : { "entity_created" : "Created entity" } }
        }
      },
      { "entity_save" : { "data" : [ "entity-created" ], "immediate" : "1" } },
      { "data_set" : { "data" : [ "node:field-c" ], "value" : [ "entity-created" ] } },
      { "entity_save" : { "data" : [ "node:field-c" ], "immediate" : "1" } }
    ]
  }
}

上記のルールは、用語[node:field-a][node:field-b](=「フィールドC」に格納される値)がすでに存在する場合、検証を実行しません。代わりに、ルールアクションがトリガーされるたびに(つまり、「記事が表示されるたび」)、その用語(すでに存在している可能性があります)を無条件に別のタイミングで作成します。したがって、これらの重複する用語(例ではhelloworldのように)を取得するのはそのためです。

その解決策(修正)は、ルールにいくつかの追加ロジックを追加して、3番目(= entity_create)および4番目(= entity_save)のルールアクションのみを実行することです。ルールアクションは、用語がまだ存在しない場合にのみ実行されます。

そのようなextaロジックを実装するには、基本的に2つのソリューション/アプローチがあります。

  • Conditional Rules モジュールを使用します。これにより、ルールアクションに同等のルール条件を含めることができます。
  • これらの2つのルールアクションを適切な(新しい)ルールコンポーネントに移動します。ここで、必要なルール条件を追加できます。そして、ルールでは、そのルールコンポーネントを呼び出す(実行する)だけです。

最初のソリューションの利点は、ロジック全体が単一のルールに含まれていることですが、(欠点)さらに別のモジュールが必要です。

どちらのソリューションでも、基本的には「フィールドCの用語がまだ存在しない場合は、すぐに作成して、その用語をフィールドCの値として使用できるようにする」などの方法でこのルールを改善します。

簡単でしょう? ...知っておく必要があるのは、「その用語が分類の用語のリストにすでに含まれている場合」を確認するためにルールで実際にチェックを実行する方法です。

パート2-条件付きルールを使用したソリューション

以下は、条件付きルールを使用した可能な解決策です。改善されたルールは次のようになります。

{ "rules_combine_taxonomy_terms_without_creating_duplicates" : {
    "LABEL" : "Combine taxonomy terms without creating duplicates",
    "PLUGIN" : "reaction rule",
    "OWNER" : "rules",
    "REQUIRES" : [ "rules", "rules_conditional" ],
    "ON" : { "node_view--article" : { "bundle" : "article" } },
    "DO" : [
      { "drupal_message" : { "message" : "Value of term for field C will be set to: \u003Cstrong\u003E[node:field-a][node:field-b]\u003C\/strong\u003E." } },
      { "variable_add" : {
          "USING" : { "type" : "text", "value" : "[node:field-a][node:field-b]" },
          "PROVIDE" : { "variable_added" : { "combined_term" : "Combined Term" } }
        }
      },
      { "entity_query" : {
          "USING" : {
            "type" : "taxonomy_term",
            "property" : "vocabulary",
            "value" : [ "node:field-a:vocabulary" ]
          },
          "PROVIDE" : { "entity_fetched" : { "existing_terms" : "Existing Terms" } }
        }
      },
      { "variable_add" : {
          "USING" : { "type" : "boolean", "value" : "0" },
          "PROVIDE" : { "variable_added" : { "new_term_exist" : "New term exists" } }
        }
      },
      { "LOOP" : {
          "USING" : { "list" : [ "existing-terms" ] },
          "ITEM" : { "current_term" : "Current term" },
          "DO" : [
            { "CONDITIONAL" : [
                {
                  "IF" : { "text_matches" : { "text" : [ "current-term:name" ], "match" : "[combined-term:value]" } },
                  "DO" : [
                    { "data_set" : { "data" : [ "new-term-exist" ], "value" : "1" } },
                    { "data_set" : { "data" : [ "node:field-c" ], "value" : [ "current-term" ] } },
                    { "drupal_message" : { "message" : "Term \u003Cstrong\u003E[node:field-a][node:field-b]\u003C\/strong\u003E already exists (no need to create it now)." } }
                  ]
                }
              ]
            }
          ]
        }
      },
      { "CONDITIONAL" : [
          {
            "IF" : { "data_is" : { "data" : [ "new-term-exist" ], "value" : "0" } },
            "DO" : [
              { "entity_create" : {
                  "USING" : {
                    "type" : "taxonomy_term",
                    "param_name" : "[combined-term:value]",
                    "param_vocabulary" : "tags"
                  },
                  "PROVIDE" : { "entity_created" : { "term_created" : "Created term" } }
                }
              },
              { "entity_save" : { "data" : [ "term-created" ], "immediate" : "1" } },
              { "data_set" : { "data" : [ "node:field-c" ], "value" : [ "term-created" ] } },
              { "drupal_message" : { "message" : "Term \u003Cstrong\u003E[node:field-a][node:field-b]\u003C\/strong\u003E did not yet exist and was created just now." } }
            ]
          }
        ]
      },
      { "entity_save" : { "data" : [ "node:field-c" ], "immediate" : "1" } },
      { "drupal_message" : { "message" : "\u003Cstrong\u003ENote\u003C\/strong\u003E: After updating field A or B, a page refresh is needed to actually SEE a value of field C = \u003Cstrong\u003E[node:field-a][node:field-b]\u003C\/strong\u003E." } }
    ]
  }
}

消化することは明らかなルールではありませんが(おそらく)、主に次のことを行います。

  • entity_queryを実行して、フィールドAで使用されている語彙(existing_termsnode:field-a:vocabularyに従って)の既存の用語のリスト(entity_queryに格納されている)を作成します。したがって、フィールドAとフィールドCは同じ語彙を使用することが前提です(質問にはそれに関する詳細はありません)。そうでない場合は、その語彙を適切なものに置き換えるか、単にハードコーディングするだけです。
  • マシン名new_term_existを使用してブール変数を計算します。これは、フィールドCに保存される用語がすでに存在するかどうかを確認します。
  • フィールドCの値を既存の用語に設定します(既に存在する場合)。
  • フィールドCの用語をその場で作成し(まだ存在しない場合)、それを使用してフィールドCの値を設定します。

ただし、最後のルールアクションのメッセージに詳細が記載されているように、1つの細かい注意事項があります。これに対処することに興味のある方は(そのメッセージを廃止するため)、追加の回答を投稿して自由に使用してくださいこのルールはここから始まります。

:理論的には、条件付きルールの代わりにルールコンポーネントを使用することもできるはずです( " 条件付きルールモジュールを使用する代わりの選択肢は何ですか? "詳細については)、この場合の主な課題は、そのようなルールコンポーネントに値を渡すときにデバッグが難しい問題が発生することです。フィールドCの値は空白のままです(たとえば、新しいノードを作成するとき)。

PS:Q:どのように象を食べますか? [〜#〜] a [〜#〜]:一度に1口...(のみ1かみました).

2
Pierre.Vriens

ルール条件RL Alias Existsは、yesと2つのルールに入れれば、このシナリオに最適です。 no。分類用語にはエイリアスが作成されるので、Cを使用する前に/taxonomy_vocabulary/[A][B]が存在するかどうかを簡単に確認できます。

ノードが作成または更新されると、ルールはAとBが一緒に追加されるかどうかをチェックして、すべての分類用語にエイリアスがあるため、そのAB分類用語がすでに存在するかどうかを確認します。すでに存在する場合(yes)、ルールはそれをフェッチして使用し、存在しない場合(no)、それを作成します。

たとえば、A:NewおよびB:Yorkでノードを初めて作成または更新するとき、「/ cities/newyork」は存在しないため、作成します。次にA:NewおよびB:Yorkを使用するとき、ルールは既存の用語を見つけてそれをフェッチします。

以下は、単一言語の分類用語を想定しています。 ノードは多言語にすることができます。

PSUEDO-RULES

Rule 1 - Taxonomy C exists
Events: Node is saved / Node is updated
Condition: URL Alias Exists > Use replacement patterns to join A and B in Value field
              eg. taxonomy/[a][b]
Action: Create variable > [a][b] 
Action: Fetch Entity by Property > Taxonomy Term > Name > Created Variable
Action: Set Data Value > C: Fetched Entity:0

Rule 2 - Taxonomy C doesn't exist yet
Events: Node is saved / Node is updated
Condition: NOT URL Alias Exists > Use replacement patterns to join A and B in Value field
Action: Create entity > Taxonomy Term > "AB" using replacement patterns 
              (not the drop-down list!) 
Action: Set Data Value > C: Created Entity

ルールのエクスポート
これらのルールをテストするには、Drupal Articles、Tagsをインストールし、URLをいじるPathautoを使わないでインストールする必要があります。
タグボキャブラリの記事に3つの用語参照フィールドを追加します。

Machine Names
field_tax_tags_a 
field_tax_tags_b 
field_tax_tags_c

ルール1-AB用語が存在するため、フェッチします

{ "rules_exists" : {
    "LABEL" : "Exists",
    "PLUGIN" : "reaction rule",
    "OWNER" : "rules",
    "REQUIRES" : [ "rules", "path" ],
    "ON" : {
      "node_insert--article" : { "bundle" : "article" },
      "node_update--article" : { "bundle" : "article" }
    },
    "IF" : [
      { "path_alias_exists" : { "alias" : "tags\/[node:field-tax-tags-a][node:field-tax-tags-b]" } }
    ],
    "DO" : [
      { "variable_add" : {
          "USING" : {
            "type" : "text",
            "value" : "[node:field-tax-tags-a][node:field-tax-tags-b]"
          },
          "PROVIDE" : { "variable_added" : { "variable_added" : "Added variable" } }
        }
      },
      { "entity_query" : {
          "USING" : {
            "type" : "taxonomy_term",
            "property" : "name",
            "value" : [ "variable-added" ],
            "limit" : "1"
          },
          "PROVIDE" : { "entity_fetched" : { "entity_fetched" : "Fetched entity" } }
        }
      },
      { "data_set" : { "data" : [ "node:field-tax-tags-c" ], "value" : [ "entity-fetched:0" ] } }
    ]
  }
}

ルール2-AB用語が存在しないため作成する

{ "rules_doesn_t_exist" : {
    "LABEL" : "Doesn\u0027t exist",
    "PLUGIN" : "reaction rule",
    "OWNER" : "rules",
    "REQUIRES" : [ "rules", "path" ],
    "ON" : {
      "node_insert--article" : { "bundle" : "article" },
      "node_update--article" : { "bundle" : "article" }
    },
    "IF" : [
      { "NOT path_alias_exists" : { "alias" : "tags\/[node:field-tax-tags-a][node:field-tax-tags-b]" } }
    ],
    "DO" : [
      { "entity_create" : {
          "USING" : {
            "type" : "taxonomy_term",
            "param_name" : "[node:field-tax-tags-a][node:field-tax-tags-b]",
            "param_vocabulary" : "tags"
          },
          "PROVIDE" : { "entity_created" : { "entity_created" : "Created entity" } }
        }
      },
      { "data_set" : { "data" : [ "node:field-tax-tags-c" ], "value" : [ "entity-created" ] } }
    ]
  }
}

その後、AとBのみを使用していくつかの記事を作成および編集します。Cの一致では、複製の代わりに、既存の用語がフェッチされます。

3
Niall Murphy