Codename One – Swap Grid Cells

What is Codename One?

The platform “Codename One” offers operating system-independent development of apps for smartphones. An important component is a library for user interfaces. Codename One is a successor of LWUIT, which in turn uses concepts of the Java Swing library.

To develop a user interface, you insert the various controls such as labels, buttons or input fields in a container object. The positioning is not handled by the container itself, but by an associated object of the class layout manager. For example, you attach a Gridlayout object to position the items in a table. This is often very useful, because the Gridlayout object will automatically adjust the positions and sizes for various display sizes.

Continue reading “Codename One – Swap Grid Cells”

(Deutsch) Ruby On Rails Datenbankoptimierung Teil 2

[Zu Teil 1]

Verknüpfungen mit dem SQL-join

Relationale Datenbanken erlauben es, Tabellen miteinander zu verknüpfen. In SQL gibt es für diese Verknüpfung das Schlüsselwort “JOIN“. Eine solche Verknüpfung kann theoretisch sehr frei spezifiziert werden, in der Praxis wird man fast immer aufgrund der Gleichheit bestimmter ID-Spalten verknüpfen.

In unserem Beispiel eines Schiffsinformationssystems haben wir eine Tabelle “vessels” mit den Schiffsdaten und eine Tabelle “countries” mit den Daten zu einem Flaggenstaat. Typischerweise wollen wir die Schiffsdaten zusammen mit der Daten des dazugehörigen Flaggenstaates ausgeben. Dazu verknüpfen wir die Tabellen an Hand des Fremdschlüssels “legal_country_id”.

In unserem Beispiel liefert der SQL-Join eine Tabelle, in der Schiffe gleich mit den dazugehörigen Flaggenstaaten eingetragen sind. Die Daten dieser Tabelle kann man zum Beispiel auf einer Übersichtseite darstellen. Es ist nur eine Datenbankabfrage nötig, obwohl man Daten aus zwei Tabellen anzeigt.

Es stellt sich dann allerdings die Frage, was eigentlich mit Schiffen ohne Flaggenstaat passiert?

Um das steuern zu können gibt es verschiedene “Geschmacksrichtungen” des Joins:

INNER JOIN: Beide Datensätze müssen vorhanden sein. Wenn einem Schiff (noch) kein Flaggenstaat zugewiesen wurde, wird es auch nicht geliefert.

OUTER JOIN, LEFT JOIN: Es wird auch dann ein Ergebnis geliefert, wenn es keinen verknüpften Datensatz gibt. Es werden also auch Schiffe ohne definierten Flaggenstaat geliefert. Dabei werden Daten aus der ersten (in Leserichtung linken) Tabelle geliefert.

RIGHT JOIN Es wird auch dann ein Ergebnis geliefert, wenn es nur in der zweiten Tabelle einen Datensatz gibt. Ein RIGHT JOIN würde also Staaten liefern, in denen kein Schiff registriert sind. In der Praxis ist das öfter verwirrend als nützlich, so dass man besser die Reihenfolge umdreht und dann einen LEFT JOIN nimmt.

Wie nutzt man join von Rails

Zunächst gibt es in Ruby schon eine Methode, die “join” heißt, die aber semantisch etwas ganz anderes macht. Sie verbindet die Elemente eines Array zu einem String:

[1, 2, 3, 4].join(‘-‘)
‘1-2-3-4’

Zusätzlich bietet ActiveRecord bzw. ActiveRelation eine Methode “joins”. Wichtig ist das “s” am Ende. Die Methode sieht zunächst sehr vielversprechend aus.

company = Company.find_by_name(‘Hapag-Lloyd’)

company.container_vessels.joins(:legal_country)

SQL:

SELECT “container_vessels”.*

FROM “container_vessels”

INNER JOIN “countries” ON “countries”.”id” = “container_vessels”.”legal_country_id”

WHERE “container_vessels”.”company_id” = 3

Leider liefert die Magie von Ruby-on-Rails diesmal nicht das gewünschte. Es wird zwar ein SQL-Join erzeugt, die Spalten der anderen Tabelle werden jedoch weggeschmissen. Active-Record ist ein sogennanter Object-Relation-Mapper (ORM), und als solcher darauf optimiert, immer Objekte einer Klasse zu liefern, in unserem Fall also ContainerVessel. Wenn man später auf die verknüpften Objekte zugreift, werden diese doch wieder einzeln geholt.

ActiveRecord-Abfragen liefern Objekte der jeweiligen Klasse zurück!

Einziger Effekt des generierten INNER JOIN ist, das nur Schiffe mit existierenden Flaggenstaat geliefert werden.

Das zeigt auch auf, wofür die joins() Methode trotzdem gut: Man kann mit ihr Objekte aufgrund von Eigenschaften von verknüpften Objekten auswählen.

Beispielsweise kann man so alle Schiffe einer Reederei auswählen, die einen EU-Flaggenstaat haben.

hapag.container_vessels.joins(:legal_country).where('countries.in_eu' => 'true')
hapag.container_vessels.joins(:legal_country).where(:countries => {:in_eu => true})

SELECT “container_vessels”.*

FROM “container_vessels”

INNER JOIN “countries” ON “countries”.”id” = “container_vessels”.”legal_country_id”

WHERE “container_vessels”.”company_id” = 3 AND “countries”.”in_eu” = ‘t’

Der SQL-Join führt dazu, das die passenden Datensätze schon in der Datenbank ausgewählt werden. Der Rails-Prozess sieht die Country-Datensätze noch nicht mal. Und was nicht da ist, kostet keinen Hauptspeicher und auch keine Performance.

In der Syntax muss man aufpassen: In der Spezifikation der Bedingungen bewegt man sich auf SQL-Ebene (‘countries’), während man in der joins-Methode die Rails-Association angibt(‘legal_country’).

(Demnächst geht es weiter mit echten Joins in Rails…) Continue reading “(Deutsch) Ruby On Rails Datenbankoptimierung Teil 2”

Optimize the Ruby-on-Rails database – part one

Reduce the number of database queries

A typical web application does many database queries before it delivers the response page to the web browser. The application needs to wait for the response of each of these database queries. It gets an additional slow down because of process switching. The database server must analyze each request, and also the communication between the database and the application takes time. So less database queries reduce the overall load on the system. The system scales better.
Continue reading “Optimize the Ruby-on-Rails database – part one”

Modification of Ilias Features

 

Examples for redesign

The learning management system Ilias can be redesigned with skins. (See previous blog entry.) But an Ilias skin can even change the functionality. I show a few examples.

Login Page

Ilias Login form redigned with a custom skin

You find the templates for login, logout and the user agreement in the folder Services / init / default

In our project, we have changed the login page:

1) The login page is important because it is visible to all visitors and not only to our participants. So branding is here especially important. In our case, we added areas with logos at the top and the bottom. We also also placed an image with a truck next to the login form.

2) The ability to self-registration has been removed, because the company decides who is allowed to use the system and provide the users with a login name.

<!-- BEGIN new_registration -->
  <!-- <a class="il_ContainerItemCommand" href="{CMD_REGISTER}">{REGISTER}</a> -->
<!-- END new_registration -->

3) The language switch has been removed, because our participants always speak German, otherwise they could not understand the learning content anyway.

<form action="{LANG_FORM_ACTION}" method="post" name="languageselection">
  <input name="cmd[showLogin]" type="hidden" value="1" />
  <select name="change_lang_to" onchange="this.form.submit()">
    <option value="">{TXT_CHOOSE_LANGUAGE}</option>
  </select>
</form>

AttentionAttention: Be careful when you remove such options: do not remove the annotated “brackets” (BEGIN / END). Ilias (or the template engine) is looking for them and produces errors when the brackets are missing.

Ilias upper menu area with elements you might want to remove

Upper menu area

This area is defined in the file tpl.main_menu.html in the services / MainMenu directory

In our case, we have removed the search box, because Ilias has also a menu item “Search”, and the search did not seem so important for our relatively small offers.

We have also removed the text “Logged in as xxx”, because the area is not public visible anyway, so the participants are always logged in. The “logout” link stands out better that way.

The entries in the menus themselves are not changed in this file, but in the file tpl.main_menu_list_entries.html

Ilias Permalinks

Footer with Permalinks

On (almost) every Ilias page you find a box which contains the so-called permanent link and also links to Facebook, Yahoo, etc.

For companies with a closed user group, this is not desired. We can remove the field in the file

tpl.permanent_link.html in the directory Services / Permanent

Positive side effect: you do not have to explain what a permalink is to the participants.

Rails ActiveRecord: count, length or size?

The object oriented database layer “ActiveRecord” offeres three different methods to determine the number of objects: count(), length() und size().

Alle drei Methoden liefern das gleiche Ergebnis. Was nehmen wir wann? Warum ist es überhaupt wichtig? Nimmt man die falsche Methode, dann erzeugt unsere Ruby-on-Rails-Anwendung überflüssige Datenbankabfragen oder braucht mehr Speicher als eigentlich nötig. Die Anwendung skaliert dann schlechter. Um mir die Unterschiede zwischen den Methoden leichter zu merken habe ich folgendes Schema erstellt.

Continue reading “Rails ActiveRecord: count, length or size?”

Ilias Skins

Custom adaptation of a web-based learning management system

(Translation in progress)

 Ilias is a so-called learning management system (LMS), ie a system for web-based education programs. It is a very comprehensive system. It integrates not only the content in online courses but also communication capabilities such as forums, chat and mail.

 When an organization like a company or a school uses such a system, they usually have the desire to change the design of the user interface.

Reasons for this include:

  1. Differentiation: You don’t want it your system look like all other systems.
  2. You want to customize it to your own Coperate Design, this includes the company logo and color scheme.
  3. Specific needs of users: In our project we want to simplify the usage by ommiting rarely used options.
  4. Regulations to be followed. Words and terms may be specified differently, or there may be ergonomics guidelines for the font size.

Continue reading “Ilias Skins”