Portofino tutorial part 3: Two classes and a relationship
Posted by Paolo Predonzani
on March 19, 2009
In part 1 we have installed and run Portofino. In part 2 we have created a very simple product management application with just one class and one attribute. Here we'll expand the product management application with a CATEGORY class and relate it to the PRODUCT class we already have. Finally, we'll visualize the data with a graphical portlet. All this should take approximately 10 minutes.
Proceed as we did for the first class. Go upstairs, create a new class and enter the following details:
- Name: CATEGORY
- Pretty name: category
- Pretty plural: categories
- Order: 2
- Tab: true
- ...leave the rest of the fields blank.
Then add an attribute to the newly created class. Choose "text attribute" as its type and enter the following details:
- Name: name
- Pretty name: name
- Required: true
- Length: 30
- Multiline: false
- In name, In summary and In details: all set to true
- ... leave the rest of the fields blank.
This is it for the moment. As you can see, CATEGORY is again a class with one attribute, so nothing new - we'll make the situation more interesting in the following section.
A category is a way to classify products. A category can certainly contain many products and a product - we'll assume - can only be classified by one category. Depending on which direction we read it, this is a:
- one-to-many relationship: from category to product,
- many-to-one relationship: from product to category.
In Portofino there is no distinction between the two (all relationships are navigable in both directions). So to create a relationship:
- go to the class on the "many" side of the relationship and
- add a relationship attribute to it.
In our case, PRODUCT is on the "many" side of the relationship, so go upstairs, navigate to the PRODUCTclass and click "add attribute". Select "Relationship attribute" from the picklist and fill in the form as follows:
This form is quite long, so let's see the fields one section at a time:
- Name: the name of the column. Enter 'classification'
- Pretty name: the name of the relationship as seen from the PRODUCT class. Enter 'classification'. Compare with "opposite end name" below.
- Required: set this to true, but if you get an error, read the subsection "Cannot make classification required because the table is populated".
- Opp. end class: the class at the opposite end of the relationship, i.e., CATEGORY.
- Opposite end name: the name of the relationship as seen from CATEGORY class. Enter 'products in this category'. compare with "pretty name" above.
- Opposite end order: leave blank.
- Immutable, Context, One to one, Auto connect to user: leave unchecked.
- In name: this attribute is not to be used as part of a product's name. So leave this unchecked.
- In summary: checked
- In details: checked
- Position and grouping: leave this section blank.
- Help information: leave this section blank.
Finally, click on Create.
If you see the following error message:
... don't worry. It's a very common situation. Think of what you've done so far:
- In part 2 of this tutorial you created a PRODUCT class with a name attribute. Portofino created aPRODUCT table in the database, which of course had no records yet.
- You've probably gone downstairs to create/test a few object of type PRODUCT. At this point thePRODUCT table is no longer empty.
- Here you've added a 'classification' attribute to the class. The attribute is "required". Portofino tries to create a 'classification' column with a NOT NULL constraint. This is incompatible with the fact that the table is already populated, hence the error.
Fixing the problem is easy:
- Uncheck the "required" field and click Create again. This time the attribute should be created without problems.
- Go downstairs and manually update the PRODUCT objects to make sure the 'classification' attribute has a non-empty value. Alternatively you can open your favorite SQL editing tool and run a bulk UPDATE.
- Go back upstairs and edit the 'classification' attribute, this time checking the "required" flag.
At this point you can go downstairs and test the model.
First click on the Categories tab and create a few product categories, e.g., food, clothing, vehicles and furniture.
Then click on the Products tab and create a few products. This time you need to provide two attributes: a name and a classification. For the classification, choose the value from the picklist.
Notice how the same relationship (say between Product 1 and Clothing) is seen from the two ends.
From the perspective of Product 1:
From the perspective of Clothing:
Also notice how the "pretty name" and "opposite end name" fields (defined upstairs) influence the generated user interface downstairs.
Now that we have some data, let's visualize them graphically using a pie chart portlet.
Go upstairs, select the portlets tab and click on Create. From the picklist, select "1D portlet report". Fill in the form as shown below:
You only need to worry about five fields:
- Name: enter "Products by category".
- On homepage: check this flag to display the portlet on the homepage.
- Class: choose PRODUCT. This is the main class of the report.
- Dimension: choose PRODUCT->Classification. In sql terms, this is the attribute used for the GROUP BY clause.
- Type: choose a simple Pie chart. Later you can experiment with the other types.
Click on Create and go downstairs. On the homepage you should see the result:
Hover the mouse over the pie sectors: a tooltip appears.
Click on any sector: you are redirected to a search page that lists the objects in that sector.
Relationships are an important part of any model. As an exercise, you can:
- create a class called MANUFACTURER with a text attribute called name
- relate PRODUCT to MANUFACTURER through a relationship attribute called manufacturer
- now that PRODUCT has two relationships, create a 2-D portlet report to break down products by category and manufacturer.
The reference manual contains chapters about relationships and portlets.
Finally, for a hands-on discussion of the various types of relationship (one-to-one, one-to-many and many-to-many), see the tutorial Understanding Relationships.