アクション (Actions)
データベース操作のカスタマイズ。
はじめに
データ操作は常に行われており、たとえば次のようなルールがよくあります:
- 顧客を削除するときは、その履歴も削除する必要があります。
- 商品をキャンセルするときは、注文から商品を削除し、合計金額を調整する必要があります。
- 購入を確定するときは、配送を行う別システムにデータを送信する必要があります。
アクション (actions) はまさにそのためにあり、データ操作が発生した特定の状況で実行するコードを挿入できます。
情報を挿入または変更すると、保存 (save) と保存後 (saved) のアクションが実行されます:
save: データベースでコマンドを実行する前。saved: データベースでコマンドを実行した後。
一方、情報を削除、除去、または消去すると、削除 (remove) と削除後 (removed) のアクションが実行されます。
remove: データベースでコマンドを実行する前。removed: データベースでコマンドを実行した後。
このように、フォームで何かを変更し、情報の作成・変更・削除の操作を行うと、データベースでは異なる操作が実行され、それぞれのアクション (actions) が実行されます。
データベースの トリガー について聞いたことがありますか?データベーストリガーはデータの変更があるたびに実行されます。したがって、アクション (actions) は トリガー に似ていますが、コードレベルで動作します。
各操作タイプはデータベースで異なるコマンドを実行することを思い出してください。具体的には次のとおりです:
- 作成:
insert into ... - 変更:
update ... - 削除:
delete from ...
これらのデータベースコマンドのいずれかを _db.execute(...) を通じて実行した場合、コマンドはアクションと連携できない形でデータベースに直接実行されるため、アクションは実行されません。
アクションのコードでは、多言語対応ローコードフレームワークのあらゆるリソースを利用できます。
アクションは、Netuno によって自動生成されるバックオフィスのフォームでデータ操作が発生したとき、またはコード内で次のものを使用してデータベース操作を実行したときに実行されます:
_db.insert(...)、_db.form(...).insert()、_db.insertIfNotExits(...)、_db.insertMany(...)など。_db.update(...)、_db.form(...).update()、_db.updateMany(...)など。_db.delete(...)、_db.form(...).delete()、_db.deleteMany(...)など。
つまり、コード内で多言語対応ローコードフレームワークの何らかのメカニズムを使用してデータ操作を行うと、対応するアクションが存在する場合はそれが実行されます。
ただし、データベースでコマンドを直接実行した場合は、アクションを実行できません。
Netuno が提供するデータ操作の仕組みを迂回しないよう、データベースでコマンドを直接実行することは避けることをお勧めします。
アクションのコードでは、データ操作に関連するあらゆる操作を実行できます。
データ項目 (Data Item)
データ項目 (_dataItem) は、作成・変更・削除されるデータの関係全体を含む、多言語対応ローコードフレームワークのリソースです。
_dataItem リソースを通じて、すべての情報にアクセスし、実行中の操作プロセスの詳細を確認できます。
_dataItemリソースがサポートする内容の詳細については、DataItem リソースのドキュメントを参照してください。
注意: _dataItem リソースはアクション (actions) のコードでのみ利用できます。
保存、変更、新規作成 (Save)
新しいレコードが作成されたとき、または何かが変更されたときに実行されるアクションを作成するには、このアクションのスクリプトを save と呼びます。これは、何かがデータベースに保存されていることを意味します。たとえば:
- JavaScript
- TypeScript
- Python
- Ruby
- Kotlin
- Groovy
watashi_no_app/server/actions/watashi_no_form/save.js
watashi_no_app/server/actions/watashi_no_form/save.ts
watashi_no_app/server/actions/watashi_no_form/save.py
watashi_no_app/server/actions/watashi_no_form/save.rb
watashi_no_app/server/actions/watashi_no_form/save.kts
watashi_no_app/server/actions/watashi_no_form/save.groovy
このアクションはデータベースコマンドを実行する前に実行されます。
データがデータベースに保存された後にコードを実行する場合は、saved アクションを使用します。たとえば:
- JavaScript
- TypeScript
- Python
- Ruby
- Kotlin
- Groovy
watashi_no_app/server/actions/watashi_no_form/saved.js
watashi_no_app/server/actions/watashi_no_form/saved.ts
watashi_no_app/server/actions/watashi_no_form/saved.py
watashi_no_app/server/actions/watashi_no_form/saved.rb
watashi_no_app/server/actions/watashi_no_form/saved.kts
watashi_no_app/server/actions/watashi_no_form/saved.groovy
このアクションはデータベースコマンドが実行された後に実行されます。
つまり、アプリケーション内の server/actions フォルダにフォーム(テーブル)名のサブフォルダを作成し、その中に save または saved というスクリプトを配置します。このスクリプトには、データベースコマンドの前または後に実行するコードを記述します。
データの作成かどうかを区別するには、if で _dataItem.isInsert() メソッドの結果を確認できます。たとえば:
- JavaScript
- TypeScript
- Python
- Ruby
- Kotlin
- Groovy
if (_dataItem.isInsert()) {
// 新しいデータが作成されています...
}
if (_dataItem.isInsert()) {
// 新しいデータが作成されています...
}
if _dataItem.isInsert():
# 新しいデータが作成されています...
if _dataItem.isInsert()
# 新しいデータが作成されています...
end
if (_dataItem.isInsert()) {
// 新しいデータが作成されています...
}
if (_dataItem.isInsert()) {
// 新しいデータが作成されています...
}
データの変更かどうかを区別するには、if で _dataItem.isUpdate() メソッドの結果を確認できます。たとえば:
- JavaScript
- TypeScript
- Python
- Ruby
- Kotlin
- Groovy
if (_dataItem.isUpdate()) {
// データが変更されています...
}
if (_dataItem.isUpdate()) {
// データが変更されています...
}
if _dataItem.isUpdate():
# データが変更されています...
if _dataItem.isUpdate()
# データが変更されています...
end
if (_dataItem.isUpdate()) {
// データが変更されています...
}
if (_dataItem.isUpdate()) {
// データが変更されています...
}
ID の取得
変更されている項目の ID(識別子)を取得するには:
- JavaScript
- TypeScript
- Python
- Ruby
- Kotlin
- Groovy
_dataItem.getId()
_dataItem.getId()
_dataItem.getId()
_dataItem.getId()
_dataItem.getId()
_dataItem.getId()
変更内容の確認
何が変更されているかを確認するには、getOldRecord() を使用してデータベース内の古いデータを取得し、新しいデータ getRecord() と比較できます。たとえば:
- JavaScript
- TypeScript
- Python
- Ruby
- Kotlin
- Groovy
if (_dataItem.getOldRecord().getString("email") != _dataItem.getRecord().getString("email")) {
// 注意: メールアドレスが変更されています!
}
if (_dataItem.getOldRecord().getString("email") != _dataItem.getRecord().getString("email")) {
// 注意: メールアドレスが変更されています!
}
if _dataItem.getOldRecord().getString("email") != _dataItem.getRecord().getString("email"):
# 注意: メールアドレスが変更されています!
if _dataItem.getOldRecord().getString("email") != _dataItem.getRecord().getString("email")
# 注意: メールアドレスが変更されています!
end
if (_dataItem.getOldRecord().getString("email") != _dataItem.getRecord().getString("email")) {
// 注意: メールアドレスが変更されています!
}
if (_dataItem.getOldRecord().getString("email") != _dataItem.getRecord().getString("email")) {
// 注意: メールアドレスが変更されています!
}
エラーの生成
操作の進行を防ぐためにエラーを生成できます。エラーの生成は通常、データベースコマンドを実行する前に行うため、たとえば save アクションで次のようにします:
- JavaScript
- TypeScript
- Python
- Ruby
- Kotlin
- Groovy
_dataItem.setStatusWithError()
.setErrorTitle("メールアドレス")
.setErrorMessage("メールアドレスは変更できません。")
_dataItem.setStatusWithError()
.setErrorTitle("メールアドレス")
.setErrorMessage("メールアドレスは変更できません。")
_dataItem.setStatusWithError()
.setErrorTitle("メールアドレス")
.setErrorMessage("メールアドレスは変更できません。")
_dataItem.setStatusWithError()
.setErrorTitle("メールアドレス")
.setErrorMessage("メールアドレスは変更できません。")
_dataItem.setStatusWithError()
.setErrorTitle("メールアドレス")
.setErrorMessage("メールアドレスは変更できません。")
_dataItem.setStatusWithError()
.setErrorTitle("メールアドレス")
.setErrorMessage("メールアドレスは変更できません。")
エラーの確認
データベースでのコマンド実行中にエラーが発生したかどうかを確認できます。さまざまなエラーが発生する可能性があります。たとえば:
- メールアドレスの重複は許可されていません。
- 必須項目が正しく入力されていません。
- その他多数。
エラーの確認は通常、データベースコマンドの実行後に行うため、たとえば saved アクションで次のようにします:
- JavaScript
- TypeScript
- Python
- Ruby
- Kotlin
- Groovy
if (_dataItem.isError()) {
// エラーが発生し、データを保存できませんでした...
}
if (_dataItem.isError()) {
// エラーが発生し、データを保存できませんでした...
}
if _dataItem.isError():
# エラーが発生し、データを保存できませんでした...
if _dataItem.isError()
# エラーが発生し、データを保存できませんでした...
end
if (_dataItem.isError()) {
// エラーが発生し、データを保存できませんでした...
}
if (_dataItem.isError()) {
// エラーが発生し、データを保存できませんでした...
}
セットアップ
データベースのセットアップ (setup) 中にデータ変更が行われた場合にのみ実行される特定の action を用意できます。
たとえば:
- JavaScript
- TypeScript
- Python
- Ruby
- Kotlin
- Groovy
watashi_no_app/server/actions/watashi_no_form/setup_save.jswatashi_no_app/server/actions/watashi_no_form/setup_saved.js
watashi_no_app/server/actions/watashi_no_form/setup_save.tswatashi_no_app/server/actions/watashi_no_form/setup_saved.ts
watashi_no_app/server/actions/watashi_no_form/setup_save.pywatashi_no_app/server/actions/watashi_no_form/setup_saved.py
watashi_no_app/server/actions/watashi_no_form/setup_save.rbwatashi_no_app/server/actions/watashi_no_form/setup_saved.rb
watashi_no_app/server/actions/watashi_no_form/setup_save.ktswatashi_no_app/server/actions/watashi_no_form/setup_saved.kts
watashi_no_app/server/actions/watashi_no_form/setup_save.groovywatashi_no_app/server/actions/watashi_no_form/setup_saved.groovy
削除 (Remove)
レコードが削除されたときに実行されるアクションを作成するには、このアクションのスクリプトを remove と呼びます。これは、何かがデータベースから削除されていることを意味します。たとえば:
- JavaScript
- TypeScript
- Python
- Ruby
- Kotlin
- Groovy
watashi_no_app/server/actions/watashi_no_form/setup_remove.js
watashi_no_app/server/actions/watashi_no_form/setup_remove.ts
watashi_no_app/server/actions/watashi_no_form/setup_remove.py
watashi_no_app/server/actions/watashi_no_form/setup_remove.rb
watashi_no_app/server/actions/watashi_no_form/setup_remove.kts
watashi_no_app/server/actions/watashi_no_form/setup_remove.groovy
このアクションはデータベースコマンドを実行する前に実行されます。
データベースからデータが削除された後にコードを実行する場合は、removed アクションを使用します。たとえば:
- JavaScript
- TypeScript
- Python
- Ruby
- Kotlin
- Groovy
watashi_no_app/server/actions/watashi_no_form/setup_removed.js
watashi_no_app/server/actions/watashi_no_form/setup_removed.ts
watashi_no_app/server/actions/watashi_no_form/setup_removed.py
watashi_no_app/server/actions/watashi_no_form/setup_removed.rb
watashi_no_app/server/actions/watashi_no_form/setup_removed.kts
watashi_no_app/server/actions/watashi_no_form/setup_removed.groovy
このアクションはデータベースコマンドが実行された後に実行されます。
つまり、アプリケーション内の server/actions フォルダにフォーム(テーブル)名のサブフォルダを作成し、その中に remove または removed というスクリプトを配置します。このスクリプトには、データベースコマンドの前または後に実行するコードを記述します。
関連との競合
データモデルによっては、別のテーブル(これも別のフォームです)との関連で使用されているレコードを削除する場合、関連が壊れるのを防ぐために削除できないことがあります。
そのため、削除のデータベースコマンドの後に実行される removed アクションで、次のようにしてこのエラーが発生するかどうかを確認できます:
- JavaScript
- TypeScript
- Python
- Ruby
- Kotlin
- Groovy
if (_dataItem.isStatusAsError() && _dataItem.isStatusAsRelations()) {
_log.error(
"テーブルとの関連があるため削除できませんでした "
+ _dataItem.getRelationTable() + " が ID " + _dataItem.getRelationItem().getInt("id") + " を使用しています"
)
}
if (_dataItem.isStatusAsError() && _dataItem.isStatusAsRelations()) {
_log.error(
"テーブルとの関連があるため削除できませんでした "
+ _dataItem.getRelationTable() + " が ID " + _dataItem.getRelationItem().getInt("id") + " を使用しています"
)
}
if _dataItem.isStatusAsError() and _dataItem.isStatusAsRelations():
_log.error(
"テーブルとの関連があるため削除できませんでした "
+ _dataItem.getRelationTable() + " が ID " + _dataItem.getRelationItem().getInt("id") + " を使用しています"
)
if (_dataItem.isStatusAsError() && _dataItem.isStatusAsRelations())
_log.error(
"テーブルとの関連があるため削除できませんでした "
+ _dataItem.getRelationTable() + " が ID " + _dataItem.getRelationItem().getInt("id") + " を使用しています"
)
end
if (_dataItem.isStatusAsError() && _dataItem.isStatusAsRelations()) {
_log.error(
"テーブルとの関連があるため削除できませんでした "
+ _dataItem.getRelationTable() + " が ID " + _dataItem.getRelationItem().getInt("id") + " を使用しています"
)
}
if (_dataItem.isStatusAsError() && _dataItem.isStatusAsRelations()) {
_log.error(
"テーブルとの関連があるため削除できませんでした "
+ _dataItem.getRelationTable() + " が ID " + _dataItem.getRelationItem().getInt("id") + " を使用しています"
)
}
代わりに、レコードを削除するデータベースコマンドの前に実行される remove アクションで、関連する可能性のある他のレコードの「クリーンアップ」を実装することもできます。たとえば:
- JavaScript
- TypeScript
- Python
- Ruby
- Kotlin
- Groovy
_db.form("betsu_no_form")
.where(
_db.where("watashi_no_form_id")
.equals(_dataItem.getRecord().getInt("id"))
)
.delete()
_db.form("betsu_no_form")
.where(
_db.where("watashi_no_form_id")
.equals(_dataItem.getRecord().getInt("id"))
)
.delete()
_db.form("betsu_no_form")
.where(
_db.where("watashi_no_form_id")
.equals(_dataItem.getRecord().getInt("id"))
)
.delete()
_db.form("betsu_no_form")
.where(
_db.where("watashi_no_form_id")
.equals(_dataItem.getRecord().getInt("id"))
)
.delete()
_db.form("betsu_no_form")
.where(
_db.where("watashi_no_form_id")
.equals(_dataItem.getRecord().getInt("id"))
)
.delete()
_db.form("betsu_no_form")
.where(
_db.where("watashi_no_form_id")
.equals(_dataItem.getRecord().getInt("id"))
)
.delete()
セットアップ
データベースのセットアップ (setup) 中にデータの削除が行われた場合にのみ実行される特定の action を用意できます。
たとえば:
- JavaScript
- TypeScript
- Python
- Ruby
- Kotlin
- Groovy
watashi_no_app/server/actions/watashi_no_form/setup_remove.jswatashi_no_app/server/actions/watashi_no_form/setup_removed.js
watashi_no_app/server/actions/watashi_no_form/setup_remove.tswatashi_no_app/server/actions/watashi_no_form/setup_removed.ts
watashi_no_app/server/actions/watashi_no_form/setup_remove.pywatashi_no_app/server/actions/watashi_no_form/setup_removed.py
watashi_no_app/server/actions/watashi_no_form/setup_remove.rbwatashi_no_app/server/actions/watashi_no_form/setup_removed.rb
watashi_no_app/server/actions/watashi_no_form/setup_remove.ktswatashi_no_app/server/actions/watashi_no_form/setup_removed.kts
watashi_no_app/server/actions/watashi_no_form/setup_remove.groovywatashi_no_app/server/actions/watashi_no_form/setup_removed.groovy
まとめ
アクション (actions) を使用すると、特定のデータ操作に関連する固有の処理を一元化できます。
コードを組み込むことで、整合性の保証、タスクの容易化、連携の実行、並列処理、追加の検証など、多くの有用な仕組みを提供できます。
アクションのコーディングは簡単で非常に有用であり、多言語対応ローコードフレームワークの他のあらゆるリソースを利用して拡張できます。
アクションのコードでは、多言語対応ローコードフレームワークのあらゆるリソースを利用できます。
アクションの利用を検討すれば、得られる容易さが多くの有用な戦略を強化できることをすぐに確認できます。