[OutSystems]ODC Associate Developerのサンプル問題について解説 2/3(#6-#10)

ODC Associate DeveloperはODC向けのエントリレベルの認定試験。
2023/10時点では、ODC向けの認定はこれだけ。

試験情報のPDFと一緒にダウンロードできるサンプル問題を解説する。
全部で15問で、この記事では6問目-10問目が対象。

他の問題については以下を参照
[ODC Associate Developerのサンプル問題について解説 1/3(#1-#5)](https://qiita.com/jyunji_watanabe/items/49792887f8d754dcd341)
[ODC Associate Developerのサンプル問題について解説 3/3(#11-#15)](https://qiita.com/jyunji_watanabe/items/51807993534abbb9b82b)

サンプル問題は、
https://www.outsystems.com/learn/certifications/
の、「Associate Developer (ODC) 」項目のリンク「Exam Details」でダウンロードできる資料から。「Sample Exam」がついている方のファイルが該当する。
ここでは2023/10にダウンロードしてきたファイルを使って解説していく。
サンプル問題は英語しかなかったので、この解説は英語版を見ながら書いている。

各問題のタイトルは、Details Sheet日本語版のトピック名で、問題に対応していそうなものを選んでいる。

# 6 Aggregate
Aggregateの編集画面で、特定のAttributeを選択⇒右クリック⇒Hideを選択、とすることで編集画面で（のみ）非表示にできる。

その操作の影響を問う問題。

この操作は、Aggregateの編集画面で表示されなくなるだけで、実行時には取得・表示される。
ただし、対象Attributeが画面等から使われていないと、OutSystemsの最適化機能により取得されなくなる。

A：×　App内で使われないAttributeはAggregateの編集画面で表示されない、という記述だが、そんなことはない。
B：×　HideされているAttributeを呼び出し側のAppで使おうとするとエラーが出るという記述だが、そんなことはない。
C：×　HideされているAttributeはAggregateのOutputを介して利用することはできない、という記述があるがそんなことはない。
D：〇　↑の説明に概ね合致する。「Appで使われているかどうかにかかわらずHideされたAttributeはAggregateのOutputで利用可能である」というのは微妙な表現。使われていなければ取得が省略されるはずで、その場合はさすがに使用できない。ただ、利用するようにロジックを変えてPublishすると取得されるようになるので、やはり使用可能になる（はず）。というわけで若干微妙だが、他の選択肢が×なので、これが正解でよいだろう。

# 7 ページネーションとソート
ScreenにStartIndexというLocal Variableがある。ScreenにはPagination Widgetを配置してあるが、このStartIndexの役割は何か？　という問題。

Paginationは表示対象のデータをページ（画面で使う条件でフィルタ・ソートした一定数のレコードごとに区切ったもの）に分割して表示するためのWidget。

スクリーンショット内のInput Parameterでいうと
- StartIndex: ページ内の先頭位置（0スタートのインデックス）
- MaxRecords: ページに含めるデータ件数
- TotalCound: Listに紐づけたデータセットの総レコード数（ページで区切らない合計）

を設定する。
例として1ページ10件で表示する場合、MaxRecordsは10にする。StartIndexは1ページ目表示時は0、2ページ目表示時は10。

よって、Pagination Widgetの各ページが始まる位置を示している、とした選択肢Aが正解。

# 8 データを表示するウィジェット 
Table WidgetのSortの実装についての問題。

テーブルヘッダの列をクリックすると、対応するAttributeでソートした結果を表示する、という要件。
こういう問題の時は、Entityをドラッグ＆ドロップすることで自動生成される画面に標準的な実装がされているので参照するとよい。

というわけで、自動生成された一覧画面のOnSortを見ると以下の通り。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/332987/e4e623f2-46f1-a318-e181-3471e01832ee.png)

問題文についているスクリーンショットでは、Refresh Dataしか入っていないのでその差分が足りていない。
差分は以下の通り
1. TableSortにクリックした列に対応するAttribute名をセット
1. 同じ列をクリックしたときは、昇順・降順を切り替える
1. ページ位置を先頭に戻す（これは、ページングの前提が現在のソート条件であるため、ソート条件が変わった時には、現在の位置が無意味になるから）

この中で2については、昇順・降順の切り替えについて問題文に言及が無いため不要。
3は本当は必要だと思うが、選択肢にないので検討から除外する。

選択肢BとCがRefresh Dataの前にAssignを配置してTableSortを上書きすることに言及している。違いは、
B. TableSort = GetMovies.List.Current (Tableに紐づけたListの現在位置のレコード）
C. TableSort = SortBy (OnSortのInput Parameter）

Bは、ソートする列を指定したいのに、行のレコードを渡されても意味が無いので×。
TableのOn Sortイベントハンドラーには、ClickedColumnを設定することで、クリックした列のSort Attributeに設定した値が渡ってくる。よってCが正解。

# 9 ロールベースのセキュリティ
ManagersとEmployeesというRoleが定義されているApp内で、一覧画面上にManagersを持つユーザーのみに表示したいリンクがある。この時の実装方法を問う問題。

選択肢を見ていくと、
まず選択肢BとCについて。ODCではRoleを作成すると、Check\<Role名\> ActionがClient Action/Server Action双方で自動で用意される。よって、Managersを持つユーザーにのみTrueブランチにあるUIを見せたいIfのConditionとしては「CheckManagerRole()」であっている。よってこれらは×。

個人的には、この問題は、明確に解くための前提条件が足りないように思う。
ManagersとEmployeesというRoleがあるとき、以下の2通りのRole設計が思い浮かぶ

1 Managersは管理者権限を持つ従業員のみ、Employeessは管理者権限を持たない従業員のみがGrantされる
2 管理者は従業員でもあるためEmployeesもGrantされる。つまり管理者はManagers+Employees、一般従業員はEmployessのみを持つ

A: スクリーンショットの実装に間違いはないという記述。↑の2に基づくと正しい
D: 一覧画面のAuthorizationでEmployeeにのみチェックが入っていてManagerには入っていない。↑の1の場合、この実装では管理者がアクセスできない。よってManagersにもチェックを入れるべきという記述。↑の1に基づくと正しい

というわけで判断に迷うが、Sample Examに付属の回答を見るとD。↑の1に基づいているということ。
人事マスタと連携していたりしたら、2かな、と思う。Appにはその前提が書いていないので、似たような問題が出たら、背後の仕組みまでは想像せずに回答した方が正答率が上がるかもしれない。

# 10 クライアントアクションとサーバーアクション？
詳細画面の保存ボタンクリックハンドラーにおいて、更新用Server Action（名前はEmployee_CreateOrUpdate）に渡すInput Parameter (名前はEmployee）には何を渡すべきか。

画面はEmployeeIdを受け取ってGetEmployeeByIdというAggregateでデータを取得しており、Aggregateが返すのはEmployeeのList（もちろんIdでフィルタリングするので最大でも1レコードしか返らない）であることが読み取れる。
Server ActionのInput Parameter名から、Employeeレコードを渡せばよい。

つまり、GetEmployeeById.List.Current.Employeeを渡せばよいのでBが正解。
（List.CurrentはデフォルトでList内の先頭位置を指している。詳細画面は1レコードしか処理しないので、List.Currentが対象レコードを指している）