🚀 Welcome to MDriven Learn –  MDriven is now on Discord!  Don’t miss the latest Release Notes.
Bootcamp:Chapter 17
This page was created by Hans.karlsen on 2023-03-19. Last edited by Wikiadmin on 2026-07-29.

You will evolve the car-sales model safely, build a modal buyer picker, enforce state-based UI rules, and make the report template URL use the current MDrivenServer address.

This chapter continues from Training:Bootcamp:Chapter 16. It uses the car factory, sales-document, and report-template work created in earlier chapters, including the report template.

What you will build

By the end of this chapter, you will be able to:

  • Rename model elements and inspect the database effect before uploading the model.
  • Prepare a sales document with its seller and selected car.
  • Prevent invalid actions by checking a car's state with OCL oclIsInState.
  • Open a modal ViewModel that lets the user pick a buyer and return that selection to the sales document.
  • Use GetSystemUrl so a report template URL does not contain a fixed server address.

Before you start

  1. Open the model produced by Training:Bootcamp:Chapter 16.
  2. Confirm that MDrivenServer is running. In the Cloud dialog, use Check Server Status and verify that the application is available.
  3. Keep the web application open in a separate browser tab. The exercises below use http://localhost:5001 as the local test address.

Rename a model association and inspect the effect

Association-end names affect the model and the generated user interface. A renamed association end does not necessarily require a database schema change. Always inspect Changes before uploading.

Correct the plural association-end name

  1. In the model, double-click the CarFactorys association end.
  2. Change its name to CarFactories.
  3. Save the model.
  4. Open the Cloud dialog and select Changes.

The result should report No DB changes detected – but checksum differs. This means the model definition changed, so the server must receive the updated model, but no database schema change was detected for this rename.

  1. Upload the model to MDrivenServer.
  2. Select Check Server Status again and verify that the server is running the uploaded model version.

Test an association-end rename that affects stored data

A single association end can be stored as a foreign key in the database. Renaming such an end can therefore require MDriven to recognize that the new name represents the existing stored relationship.

  1. Locate the association from CarFactory to BrandOfCar.
  2. Rename the 0..1 BrandOfCar association end to 0..1 BrandOfCarx.
  3. Save the model and select Changes in the Cloud dialog.
  4. Review the proposed changes before uploading. Do not treat an association-end rename as equivalent to a display-only rename.
  5. Change the association-end name back to 0..1 BrandOfCar and save.

The validation messages caused by the temporary name should disappear after the original name is restored.

Use a rename operation when data must follow a renamed element

When a persisted model element changes name, use the model's rename support rather than changing a name without preserving its former identity. The purpose of FormerNames is to let evolution identify the old stored name and move or retain existing data correctly. Review the rename behavior before applying a schema-changing rename to a server with existing data.

Prepare a sales document

The sales document needs a seller and a car before it can be used in the ownership workflow.

Add seller and buyer columns

  1. Open the CarFactoryView ViewModel.
  2. Under DocumentForSales, add a column for the seller's name.
  3. Rename the generated column from Seller_Name to Seller.
  4. Add a column for the buyer's name.
  5. Rename the generated column from Buyer_Name to Buyer.

An underscore in an automatically generated ViewModel column name represents a navigation path, such as a related object's Name. Give the column a readable display name when the generated name is not appropriate for the user interface.

Create the preparation action

  1. In CarFactoryView, find the action currently named CreateAndAddDocumentForSales.
  2. Rename it to PrepareSale.
  3. Set its execute expression to create a document, add it to the factory's sales documents, and assign the current car:
Let doc=CarTransferOwnershipDocument.Create in
(
  self.DocumentForSales.add(doc);
  doc.Car:=vCurrent_CurrentlyOwnedCars
)
  1. Add columns for Car.RegistrationNumber and Car.State to the DocumentForSales grid.
  2. Save the model.

The expression sets the document's Car end. You do not also need to set the opposite association end when MDriven maintains the association.

Upload and test the changes

  1. Open the Cloud dialog, select Changes, and review the result.
  2. Upload the model.
  3. Select Check Server Status.
  4. Open the web application and verify that the sales-document grid shows Seller, Buyer, RegistrationNumber, and State.

The state machine controls the sale workflow: paperwork is created and used as part of an ownership transaction rather than being treated as an unrelated record.

Restrict document deletion by state

Remove the temporary preparation action before adding the state-based delete rule.

  1. In CarFactoryView, delete the PrepareSale widget.
  2. Select the DeleteDocumentForSales widget.
  3. In Disabled Expression, enter the expression specified for this exercise:
vCurrent_DocumentForSales->isnull or
(vCurrent_DocumentForSales.Car->oclisinstate(#InOwnershipTransaction))
  1. Save, upload, and test the action with no selected document and with documents in different car states.

oclIsInState checks whether the selected car is in the named state. A disabled expression must be true when the button must not be usable. Verify the intended behavior in the application, particularly whether deletion must be blocked while the car is in InOwnershipTransaction or while it is not in that state.

Create a modal buyer picker

A modal ViewModel is a dialog that returns a selected value to the ViewModel that opened it. In this example, the picker returns a CarDealer; the calling ViewModel assigns it as the document buyer.

Create and clean up CarDealerPicker

  1. Create a new ViewModel named CarDealerPicker.
  2. Set its class to CarDealer.
  3. Leave the ViewModel unrooted.
  4. Use UI Hints and select Copy ValueStore Auto Form. This creates a grid for the available car dealers and their attributes.
  5. Delete the ChangeTime, CreateTime, and Guid widgets.
  6. Move the Name widget up so it aligns with the Car Dealer widget.
  7. Save the ViewModel.
  8. Move the CarDealerPicker global action into the Views menu group.

Add the PickBuyer action to the sales-document grid

  1. Return to the CarFactoryView ViewModel.
  2. In the DocumentForSales grid, delete the unneeded AsString, ChangeTime, CreateTime, and Guid columns.
  3. Add a class action in the grid and name it PickBuyer.
  4. Create a ViewModel action named PickBuyer.
  5. Set Bring Up View Model to CarDealerPicker.
  6. Set the action to Is modal.
  7. Set Enable Expression For Modal Ok to:
vCurrent_CarDealer->notempty
  1. Set Expression After Modal Ok to:
vCurrent_DocumentForSales.Buyer:=vModalResult_vCurrent_CarDealer

The modal OK button is available only when the picker has a current CarDealer. After the user chooses that dealer and selects OK, vModalResult_vCurrent_CarDealer is the selected dealer returned by the modal ViewModel. The expression assigns that dealer to the selected sales document's Buyer.

Test buyer selection

  1. Save and upload the model.
  2. In the web application, open CarFactoryView, select a sales document, and choose PickBuyer.
  3. If the picker is empty, open Views/CarDealerPicker.
  4. Use the actions on the left to create three car dealers and give each dealer a name. Save the data.
  5. Return to CarFactoryView and choose PickBuyer again.
  6. Select a dealer, choose OK, and verify that the Buyer column on the sales document shows the selected dealer.

Also verify the deletion rule and sale workflow:

  • Try to delete paperwork for a document in an ownership transaction and confirm the delete action follows the configured disabled rule.
  • Initiate the sale of a new car.
  • Attempt to initiate a sale for a car already in an ownership transaction. The workflow must prevent the invalid transition.

Make the report URL server-independent

A fixed URL works only on the server address it contains. Use the system URL function so the report template URL is built from the address of the server running the model.

GetSystemUrl is provided through the SysSingleton system object. The method uses the Eco.ExternalLateBound tag value so the system can resolve the server address at runtime.

  1. Open the report template ViewModel TheTemplateForCarTransferOwnersdhipDocumentReport.
  2. Change the TemplateUrl expression so it builds the URL from the system URL and the template path:
SysSingleton.oclSingleton.GetSystemUrl + '/content/ThisWillBeMyTemplate.od'
  1. If the expression reports an error, open the SysSingleton class.
  2. Locate the operation currently named with the SysSingleton. prefix and remove that prefix so its name is GetSystemUrl.
  3. Save the model and check the TemplateUrl expression again.
  4. Upload the model to MDrivenServer.
  5. Produce a sales document and verify that the report template is found without a hard-coded server address.

Chapter result

You have inspected model evolution before deployment, created a modal buyer-selection workflow, tested a state-dependent action, and changed the report URL to obtain the server address at runtime.

See also