Tutorial Flex on Rails login system part 4: Building a login system

This tutorial is part 4 of a tutorial about Flex, Ruby on Rails and WebORB. This is the full List:

Tutorial Flex on Rails part 1: Introduction
Tutorial Flex on Rails part 2: Install Ruby on Rails
Tutorial Flex on Rails part 3: Install WebORB
Tutorial Flex on Rails part 4: Building a login system

Before we start

*We guess that you already installed Ruby on Rails. If you didn’t, here more information about the installation Ruby on Rails ##fix url
*This tutorial is based on Windows XP. It is possible that other Operation systems look different than the examples
* Make sure your Computer is not connected to localhost trough the proxy

Begin with Rails

Now we can start with Rails. Start Instant Rails, if you didn’t do this: Right mouseclick on the I in the right bottom corner of your taskbar > Rails Applications > open Ruby Console window. If everything is going alright a console is open and you are in the folder “rails_apps”.

Now we create a new Rails project by typing the next line in the console window:

> rails loginexample

If you now push ENTER you see that a lot of files are created. Wait till the prompt is back. Now you created a folder in “rails_apps” that is called loginexample.

Open your Windows explorer and go to this folder. You can find him in the directory where you installed Instant Rails, then rails_apps and then loginexample. In my case C:railsrails_appsloginexample. After that you open the “config” folder. There you find a file with the name “database.yml”. Open this file in your favorite texteditor (notepad, Notepad++, etc).

You don’t have to change anything in this file. If you look in this file you see 3 catagories: development, test and production. This are 3 different database environments that can be used to create your application. During this tutorial we only using the development environment, but it is smart to create them all every time you start a project.

We don’t have to change something, if you changed the databasename, username or password you also have to change them here. Save the changes if you made any.

Database set up

In the database.yml we refer to 3 different databases, namely: loginexample_development, loginexample_test and loginexample_production. We are now going to create those 3 databases.

Rightmouse click on the I from instantRails that is in your taskbar, go to config > database(phpmyadmin). Or just use your own favorite mySQL editor.

Now you have to create 3 databases:
* loginexample_development
* loginexample_test
* loginexample_production

After you did this select the database “loginexample_development (this is the database we will use during the whole tutorial). Create a table ”’Users”'(pay attention! Users need to be plural), and give him 3 fields:
*1st field: Name ”’id”’, type INT and select auto_increment by Extra and select primaire key
*2nd field: name ”’name”’ type VARCHAR and length 50
* 3th field: name ”’password”’ type VARCHAR and lenght 10

Now click on the save button and the user table is created. If you want you can already create some content in the database. Select the database, there is only 1 table in the database namely Users. By the collum action there is a icon that says “insert”. Now you can fill in the name and the password of the user want to create. I insert “test” in both. After that I click on “Start”. After this the user is in the table.

Scaffold and Validation

Now we have a database, and we added 1 user to it. We are now going back to the console. If everything is alright you are still in the right folder rails_appsloginexample. If not go to it.

Now type in the console:

> ruby script/generate Scaffold User Admin

You now see that some files are created. Don’t forget that we still didn’t program anything. Now we are going to start the server with one simple line (type this in the console):

> ruby script/server

The server will start (don’t close the console window)

Let’s see what we made. Open your browser and go to
http://localhost:3000/admin
If everything went right you now see a list of users. And if you just inserted a user in the database it will appear in this list

Play a little bit with the interface. Create a new user or edit one.

Now were going to windows explorer rails_appsloginexampleappmodels
Now you will see a file in there called “user.rb”, open this one in your favorite text editor

Insert this 2 rules, and in the end it will look like this:

class User < ActiveRecord::Base  validates_presence_of :namevalidates_presence_of :passwordendend

Don’t forget to save the file.

Open http://localhost:3000/ again in your browser and click on new to create a new user. Don’t fill in the name and password field, and then click on create. Now ruby says you have 2 problems: Name and password are required and can’t be empty. This is how you apply validation in Ruby on Rails. Simple as that!

Installation WebORB

Now we are going to install WebORB. Go in your console to the Ruby on Rails projectfolder rails_apps/loginexample. If you already have a console were the server is started you can also open a new console window. Than type the next line in the console and push enter (make sure you have an internet connection):

> ruby script/plugin install http://themidnightcoders.net:8089/svn/weborb

The console will show you some lines that something is downloaded and installed. This may take a while. If everything is ready you can start testing WebORB. Restart your server. Go to the console window were your server is still running and push on CTRL –C.
The server will stop. After the server is stopped you type in the console:

> ruby script/server

Open your browser and then navigate to http://localhost:3000/examples/example.html Push on the button “Get Computer Info”, if everything goes alright every field in the form will be filled. Nice, now everything is working, this means that Flex has a connection with Ruby on Rails. Let’s start making something for our own.

Making a controller in Ruby on Rails

Before we start making our own controller for Flex we are first making a TestController to see what is possible. Open again a console window, go to the right folder rails_apps/loginexample and type the next line, followed with a enter:

> ruby script/generate Controller Test

Some files will be created. Now we will edit one file of this.

Open windows explorer and go to the folder loginexample/app/controller (for me: C:railsrails_appsloginexampleappcontrollers). In this folder there is a file called test_controller.rb, this is the file we just created. We open this file in our favorite texteditor. There is not a lot in this file, only:

class TestController < ApplicationControllerend

So we will add some functionality to it. Make the file look like this:

class TestController < ApplicationController  def indexrender_text "Hallo controller"

end

end

After that we are going to http://localhost:3000/test and we look what appears.

As you see, generates our controller a text, namely “Hallo Controller”. Also look to the path of the controller. Now we are going to add more so our class will look like this:

class TestController < ApplicationController  def indexrender_text "Hallo controller"

end  def dosomething

y = "hallo"

a = ""

10.times do

a += y

end

render_text a

end

end

Go to http://localhost:3000/test/dosomething. Now you will see 10 times hallo in your browser. First take a look at our URL. We just created a method “dosomething” and we call him trough test/dosomething. It is not really necessary that you know what we are doing in the method dosomething but it is nice to see how Ruby looks like normal English.

Making a service: UserService

We are now going to make a service and call it in Flex 2.0. To use the service it is necessary that webORB is installed. Now go with windows explorer to the folder loginexampleappservices (for me: C:railsrails_appsloginexampleappservices). There is 1 service in this folder called InfoService.rb. We will create a new service with the name UserService. Create a new file with the name UserService.rb of just copy InfoService.rb and rename it to UserService.rb. After that you open UserService.rb in your favorite texteditor (if you copied the file you have to delete all the unnecessary parts).

Now we can start writing our service. Make sure the service will look like the next code:

require 'weborb/context'require 'rbconfig'class UserServicedef login (userName, userPassword)

"hallo " + userName + " with password " + userPassword

end

end

What are we doing here? We created a service with the name UserService. Standard this file is loading “weborb/context” and “rbconfig”. After that we made a function “login”. This function requires a “username” and a “userPassword”. Eventually we are sending this variables back in a string: “hallo userName with password userPassword”. Isn’t it really clear? It will if we call this service in Flex.

We have to do 1 important thing before we go to the Flex side. We have to make this service known. We need that to make sure that Flex can call the service.

Making the service known

We are now going to make the service known. Go with windows explorer to the folder loginexample/config/WEB-INF/flex (for me: C:railsrails_appsloginexampleconfigWEB-INFflex). This folder contains some configuration files, under which remoting-config.xml. Open this file in your texteditor. As you see there are already some services defined in this file. We are creating an extra service, called UserService that will look like this:

<destination id="UserService">
<properties>
<source>UserService</source>
</properties>
</destination>


You can also copy InfoService and edit id and source. The destination id is the name that we will call in Flex, the source is the path were Ruby can find our service Userservice. Save the file. Now we can start building in Flex.Start a project in FlexNow we are going to build a simple login application in Flex. Start Adobe Flex Builder. If you have any projects open you should close them. Now click on the top menu on: File > New > Flex Project, now a window will open.Click on the radiobutton Flex Data Services and “Compile application locally” should also be selected. After that you click on “Next”Uncheck the “Use default location for local Flex Data Services server” if this one was checked. Now we browse to our project root folder (in my case: C:railsrails_appsloginexampleconfig). As Root URL we type: http://localhost:3000/weborb and push on “Next”.

We give the project the name “loginexample”. If you don’t wan’t the project saved in the standard folder than you have to change the location

Click again on “Next” (NOT ON “FINISH”!). We change the Output folder to loginexamplepublicexamples) and the Output folder URL to http://localhost:3000/examples. Now we can click on the finish button and our project will be created

We can test our project by compiling the project (the green button above the toolbar). The browser will be empty. If everything is alright the location is http://localhost:3000/examples/loginexample.html. Now we started our project and we can start building the login application.

Building a Login interface in Flex

Your loginexample.mxml will look like this:

<?xml version="1.0" encoding="utf-8"?><mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute"></mx:Application>

Everything that we build will be put between the . We build a Panel and in that panel we have 2 labels and 2 textinputs and 1 button. I expect that you already played around with flex so this is not a difficult task.

Here is the first part of the code:

<mx:Panel title="Login" width="329" height="178" layout="absolute">  <mx:Label text="Name"  y="20" x="40"/><mx:TextInput id="nameLogin_fld" x="104" y="18"/>

<mx:Label text="Password"  x="40" y="60"/>

<mx:TextInput id="passwordLogin_fld" x="104" y="58" displayAsPassword="true"/>

<mx:Button x="234" y="106" label="Login"/>

</mx:Panel>

If you now click the login button nothing will happen. To make something happen we add the “click” function to the button. The code of the button will look like this:

<?xml version="1.0" encoding="utf-8"?><mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute"><mx:Script>

<![CDATA[      import mx.controls.Alert;

private function userLogin():void {

Alert.show("Call Login");

}

]]>

</mx:Script>
  <mx:Panel title="Login" width="329" height="178" layout="absolute">    <mx:Label text="Name"  y="20" x="40"/><mx:TextInput id="nameLogin_fld" x="104" y="18"/>

<mx:Label text="Password"  x="40" y="60"/>

<mx:TextInput id="passwordLogin_fld" x="104" y="58" displayAsPassword="true"/>

<mx:Button x="234" y="106" label="Login" click="userLogin()"/>

</mx:Panel></mx:Application>

Save the project and compile the application (green play button). Now click on the login button and you will see that the function is called. You get an alert popup with the notice “Call login”. Our first flex application succeeded.

Communication between Flex and Ruby on Rails

A Flex interface is ofcourse nice but we want the that the Flex side is communicating with the Ruby on Rails side. For this communication we use a RemoteObject. The RemoteObject has to be created immediately when the application is started. If we don’t do this we can’t make a call to Ruby on Rails. First we make a function that is called when the application is started.

<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute"creationComplete="onCreationComplete()">  <mx:Script><![CDATA[      public function onCreationComplete() : void {

}

]]>

</mx:Script>

In this applicationtag we put creationComplete=”aFunction()”, in our case we call a function named onCreationComplete(). We put the onCreationComplete() also in the script tag. As you see now the onCreationComplete() is doing nothing but we will change this. Now we create the RemoteObject

/*if all the imports aren’t created automatically than this should also be added after the CDATA*/import mx.rpc.events.ResultEvent;import mx.rpc.events.FaultEvent;import mx.rpc.remoting.RemoteObject;

/* declare every object, our loginController is of the type RemoteObject */

private var loginController : RemoteObject;

public function onCreationComplete() : void {

/*First we create a RemoteObject*/

loginController = new RemoteObject();

/* We give the destination of our Object that we created earlier in the remoting-config.xml (making the service known) */

loginController.destination = "UserService";

/* This one is listening if there is some result is coming back, if there is result, the onLoginResult function will be called*/

loginController.login.addEventListener("result", onLoginResult);

/* This one is listening if some errors come back, and makes sure that a fault will be send to the onFault function*/

loginController.addEventListener("fault", onFault);

}

We now made a RemoteObject that is calling our service. This RemoteObject is listening if there is something coming back and what it is. Now we make the functions that will handle the result our fault.

/* If there is result this function will be called*/private function onLoginResult(event : ResultEvent):void {Alert.show("We have result!");}/* If something goes wrong this function will be called*/

private static function onFault (event : FaultEvent):void {

Alert.show("error: something is wrong");

}

If there is result an Alert box with the text “We have result” will be visible. If something goes wrong we get an Alert box with the text “error: something is wrong”.

Now we have to trigger our RemoteObject to do something. Most often this will happen after an user action, for example when an user clicks on a button. This is the same with our application. When the user clicks the login button we want them to login. We already made this action we only have to modify the userLogin() function a little bit.

private function userLogin():void {/*Alert.show("Login called");*/  loginController.login(nameLogin_fld.text, passwordLogin_fld.text);}

We call our service loginController (UserService) that contains “login”. And we give the fields name and password. The whole application will look like this:

<?xml version="1.0" encoding="utf-8"?><mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute"creationComplete="onCreationComplete()">

<mx:Script>

    <![CDATA[

import mx.rpc.events.ResultEvent;

      import mx.rpc.events.FaultEvent;

      import mx.rpc.remoting.RemoteObject;

      import mx.controls.Alert;

      private var loginController : RemoteObject;

      public function onCreationComplete() : void {

        loginController = new RemoteObject();

        loginController.destination = "UserService";

        loginController.login.addEventListener("result", onLoginResult);

        loginController.addEventListener("fault", onFault);

      }

      private function onLoginResult(event:ResultEvent) :void {

        Alert.show("we have result!");

      }

      public static function onFault(event:FaultEvent):void {

        Alert.show("error: something is wrong ");

      }

      private function userLogin():void {

        loginController.login(nameLogin_fld.text, passwordLogin_fld.text);

      }

    ]]>

  </mx:Script>

<mx:Panel title="Login" width="329" height="178" layout="absolute">

    <mx:Label text="Name"  y="20" x="40"/>

    <mx:TextInput id="nameLogin_fld" x="104" y="18"/>

    <mx:Label text="Password"  x="40" y="60"/>

    <mx:TextInput id="passwordLogin_fld" x="104" y="58" displayAsPassword="true"/>

    <mx:Button x="234" y="106" label="Login" click="userLogin()"/>

  </mx:Panel>

</mx:Application>

Nice, now save the application, if you have any errors fix them now. Compile the application with the green playbutton. If the application is loaded you can click the login button. Wait a few seconds till the AlertBox is visible. In the most cases the first time takes a little longer if the server is just started. If everything is alright you now see an AlertBox with the text “We have result!”. If it went wrong you get an AlertBox with the text “error: something is wrong”. If you get this there is something wrong on the Ruby on Rails side, check this. If this is not helping, restart the server and empty the cash of the browser.

What is the application doing? The login button calls the function userLogin(). The userLogin() calls the RemoteObject loginController. We registerd the service in the file remote-config.xml so it is clear for flex where he can find the service. The function login is called on the Ruby on Rails side. If everything is alright Flex gets something back (it doesn’t care what Flex is getting back for now). The function onLoginResult will be called and an AlertBox will be visible.

Receive data from Ruby on Rails

It’s ofcourse nice that we can communicate with Ruby on Rails, but we want eventually is that we get something back from RoR. On this point RoR service UserService already gives something back. We only have to visualize this on the Ruby side. This is in the UserService: “Hey”+userName+ “ with password “+userPassword. userName and userPassword are both variables that we send from Flex. We also already made this. The only thing we have to do is change the next thing:

private function onLoginResult(event:ResultEvent) :void {

  /* Show the alert now */
  Alert.show(String(event.result));
}

The event.result is the object that we receive in flex from the Ruby side, in this case “Hey”+userName+ “ with password “+userPassword. Because the Alert class contains a class we but it between String(). Nice, that’s all! Let’s start testing. Save your application and solve the problems (if they pop up). After this you compile the application by clicking the green play button.

If you have any problem it is also possible that you have restart the Ruby Webtrick server. There is still a caching problem that could give problems. You can restart the server by pressing Control-C in the console window, and after that you start it again with ruby script/server followed by a ENTER

If the application is running you can start testing. Fill in a name and a password and after that click the login button. Wait a few seconds till a Alert screen is visible. If everything is alright you get an Alert box with the text: Hey{Username in flex} with password {Password send by flex}.

Congratulations you have send data to Ruby on Rails and received it again in Flex. This is a nice basic.

Ruby on Rails, get some data from a database

When we started this tutorial we made a user with the name “test” and with the password “test”. Now we want to check in our Flex application if the name and password that we fill in is the same as the name and password in the database. If everything is the same the user is allowed to log in, else the user should get a message that he logged in with the wrong data.

This means that we have to do some adjustments on the Ruby on Rails side. We have to edit the UserService. Open the UserService with your favorite texteditor.

We change the login function in UserService in the following:

require 'weborb/context'
require 'rbconfig'

class UserService

  def login( userName, userPassword )
    @user = User.find(:first,:conditions => [ "name = ? AND password = ?", userName, userPassword ])
    return  @user;
  end

end

We make a variable @user. We ask to the model User (that is connected to the database table Users) to give us the first user (:first) that is matching our conditions (:conditions). This conditions are the userName and userPassword that we send from the Flex side. And in the end of the function we return the variable @user. If we now send from Flex a login request with username and password “test” we should get some response. If we get nothing back or an empty @user. Save your UserService.

Now we start working in our Flex application. I told you a few minutes ago that we get “something” back or nothing. Nothing is equal to “null” in Flex. So this means that if we get “null” back it is not allowed for the user to login. If we get “something” back it is allowed to login. We modify the function onLoginResult()

private function onLoginResult(event:ResultEvent) :void{

  /* if the result is not null */
  if (event.result != null) {
    Alert.show("Welcome back, "+event.result.name);
  }

  /* if result is something else (in this case it is always null) */

  else {
    Alert.show("Wrong name or password");
  }
}

We are now using a if/else statement. Between the round brackets you specify what condition should be true. In this case it only should be different as null. If it is different as null the user gets an Alert with a message that everything went alright. If the if conditions result in a false the function starts the else statement, that tells the user that name or password is wrong.

The Alert in the if statement also contains the “event.result.name”. If we login correct we let Ruby send Flex his own userobject back. The userobject contains a id, name and password. You can call them in the same way you call the name.

So event.result is the object that you get back. The event.result object contains name, password and id, but it can also exist from an array

Save the application and fix the errors if you get any. Compile the application by clicking the green Play button. Now try to login with, name: “test” and password: “test”.
Now you get:

” Welcome back, test”

If something went wrong you get this:

“Wrong name or password”

“with problems it is possible that you have to restart the Ruby Webtrick server. There is still a caching problem. Start the server again by pressing control-C in your console window, after that restart the server by typing: ruby script/server followed by a ENTER”

Author Bio

5 Comments

  1. abhishek - June 11, 2008

    is there any free pdf for flex with rails to do uploading,ffmpeg and more examples ?
    abhishekchess1@gmail.com

  2. eyoel - August 7, 2008

    It is interesting Tutorial. I install WebORB and it is working fine but my problem When I create a Flex project I can’t get radiobutton Flex Data Services. Do I need to install Flex Data Service ? or I remember when creating new project in Flex 2 you can get this information but not in Flex 3. I can’t even register my WebORB server in Flex 3

    I am using Flex 3 eclipse plugin.

    please help

    Thanks

  3. Arno Manders - August 7, 2008

    Go to this site:
    http://www.themidnightcoders.com/doc30/

    and click on “Flex integration”. It is possible that there is the sollution. I don’t have a clue

  4. Tutorial Flex on Rails login system part 2: Install Ruby on Rails | Arno Manders - February 15, 2009

    […] –Tutorial Flex on Rails part 1: Introduction –Tutorial Flex on Rails part 2: Install Ruby on Rails –Tutorial Flex on Rails part 3: Install WebORB –Tutorial Flex on Rails part 4: Building a login system […]

Leave a Reply to johann Cancel reply