<?xml version="1.0" encoding="UTF-8"?>
<feed xml:lang="en-US" xmlns="http://www.w3.org/2005/Atom">
  <id>tag:www.integrallis.com:blogarticles</id>
  <link type="text/html" rel="alternate" href="http://www.integrallis.com"/>
  <title>The Integrallis Blog : </title>
  <subtitle type="html">Musings on Ruby, Groovy, Java and programming in general</subtitle>
  <updated>2009-09-08T23:34:03-04:00</updated>
  <generator uri="http://www.typosphere.org" version="4.x">Typo</generator>
  <entry>
    <id>tag:www.integrallis.com:Article27</id>
    <published>2009-08-31T16:54:46-04:00</published>
    <updated>2009-09-08T23:34:03-04:00</updated>
    <link type="text/html" rel="alternate" href="http://www.integrallis.com/blog/2009/09/08/using-gorm-to-boost-legacy-spring-applications"/>
    <author>
      <name>Joseph Nusairat</name>
    </author>
    <title type="html">Using GORM to Boost Legacy Spring Applications</title>
    <category scheme="http://www.integrallis.com/blog/category/java" term="java" label="Java"/>
    <category scheme="http://www.integrallis.com/blog/category/spring" term="spring" label="Spring"/>
    <category scheme="http://www.integrallis.com/blog/category/groovy-grails" term="groovy-grails" label="Groovy"/>
    <category scheme="http://www.integrallis.com/blog/category/grails" term="grails" label="Grails"/>
    <category scheme="http://www.integrallis.com/blog/tag/gorm" term="gorm"/>
    <category scheme="http://www.integrallis.com/blog/tag/groovy" term="Groovy"/>
    <category scheme="http://www.integrallis.com/blog/tag/grails" term="Grails"/>
    <category scheme="http://www.integrallis.com/blog/tag/spring" term="spring"/>
    <category scheme="http://www.integrallis.com/blog/tag/java" term="Java"/>
    <category scheme="http://www.integrallis.com/blog/tag/orm" term="orm"/>
    <summary type="xhtml">
      <div xmlns="http://www.w3.org/1999/xhtml">
<h3>Using GORM with your Spring application can increase the productivity and readability of your code</h3>

<p>Groovy and Grails has stormed the Java world as the new way to create reliable Web 2.0 applications in a concise and fast manner. The ability to go from the start of a project to the end, especially for a smaller demo, is exponentially faster. This is due to the many features of Grails. Out of the box applications are easier to build, create, test, and deploy because of the convention over configuration methodology. In addition Grails is written in Groovy, a dynamic language that can run on the JVM and interact as if they were Java classes. Groovy gives the power to write dynamic code with power and features that are normally unavailable in Java. Possibly the best example of this power in Groovy and Grails is the creation of the Grails Object Relational Mapper (GORM). </p>

<p>However, we can’t all just go to our managers and say “Hey, let’s rewrite this entire application in Grails”. We would more than likely get laughed out the door. At many companies it also isn’t feasible to ask for an entire framework shift. However, most of us can request “small changes”, especially if they help save time. </p>

<p>With Spring 2.0 and above we can create Spring beans out of Groovy objects. This gives us a nice ability to use Groovy nomenclature in our Spring code (e.g. the Meta Object Programming (MOP), cleaner syntax, etc). However, what we do not get with straight Groovy is a better way to interact with the database. For that we need the power of GORM. With Grails 1.1 that has become significantly easier.</p>

<h3>Why Do I Want To Use GORM?</h3>

<p>You may be familiar with Hibernate and wonder why you should bother with GORM. Hibernate is a GREAT ORM, and the framework has been developed steadily since its inception. While Spring’s wrapping of Hibernate has made it easier to interact with the database, it is still missing the readability and ease of use that most modern developers want.  The following example demonstrates how GORM brings simplicity to Hibernate code. (Please note that although GORM derives from Hibernate any mention of Hibernate here will specifically be in reference to the pure Java Hibernate form.)</p>

<p>This example starts by performing a simple query to retrieve items from the Todo table in the database where name and description matched some given text. When using Spring’s Hibernate Template, the code would look something like this:</p>

<pre class="brush: java;">
public List find(final String name, final String desc) {
final String hqlQuery =         
    "select t from Todo t where t.name = :name and t.description = :desc";
    return (List) getHibernateTemplate().execute(new HibernateCallback() {
    public Object doInHibernate(Session session) throws HibernateException {
        Query query = session.createQuery(hqlQuery);      
        query.setString("name", name);
        query.setString("desc", desc);
        return query.list();
    }
});    
}
</pre>

<p>Listing NUS-1</p>

<p>While this code does the job, something more readable would not only make it easier for everyone to understand, but would also cut down on time and errors.</p>

<p>Now if we were using Java Persistence API (JPA) supported queries we could make the code in Listing NUS-1 a bit simpler as shown in Listing NUS-2.</p>

<pre class="brush: java;">
@PersistenceContext
EntityManager manager;

public List find(final String name, final String desc) {
    final String hqlQuery =         
        "select t from Todo t \
        where t.name = :name and t.decscription = :desc";
    return manager.createQuery(hqlQuery)
        .setParameter(“name”, name)
        .setParameter(“desc”, desc)
        .returnResultList();
}
</pre>

<p>Listing NUS-2</p>

<p>This is more concise and fairly readable, but several queries in a row would require repeating the same block of code many times with slight alterations and would increase our time and effort to do so. You may be asking yourself what is the problem with this? After all I am sure many of you have witten similar or even more verbose code before. The problem lies in the fact that code should be easily readable. As good developers we want to concern ourselves with the business logic, using the write tools. We shouldn’t have to spend too much of our time deciphering easy parts of the code, and queries to the database are often just that. Using GORM helps us to solve that problem, and here’s how.</p>

<p>Let’s take what that code is doing and write it in English. The code is wanting to query the Todo table to find all by name and description. Well how do we write that out? How about this:</p>

<pre class="brush: java;">Todo.findAllByNameAndDesc(name, desc)</pre>

That is simple, concise, and in GORM that line is actual code. This begins to show the ease of using GORM over Hibernate and we will expand on that concept when using Criteria queries later. But first, let’s see how to use GORM in our Spring application.

### Injecting GORM

The interesting thing about writing an article on Using GORM with Spring is that there is barely enough setup required to fill a blog entry, let alone an entire article. In fact, you could almost Twitter the entire extra XML needed; however, for the purpose of learning we are going to go into a bit more detail. We will show not only how to set up GORM in Spring but also various options when using Spring. This will require configuring the Spring beans, installing the right JARs, and, most importantly, understanding the various ways to use GORM in your application.

### Configuring the Spring Beans
We are going to go over in this section the necessary modifications to the spring files needed for using GORM with Spring. The modifications here will be to your bean configurations and are independent of whether you are using Spring in web environment or a standalone application. That being said of course if you were to be using Spring in a web environment no modifications are needed for the web specific files (like web.xml)
The first thing to do is to add an XML namespace to your bean configuration. This one is specifically for GORM:
xmlns:gorm="http://grails.org/schema/gorm" 

Once the namespace is set you will be able to use the GORM Session Factory instead of the Hibernate Session Factory. Listing NUS-3 is an example of the GORM bean definition that would go into your bean definition file..

<pre class="brush: java;">
 <gorm:sessionFactory 
     base-package="com.integrallis.demo.domain"
     data-source-ref="dataSource"
     message-source-ref="messageSource">
     <property name="hibernateProperties">
        <util:map>
          <entry key="hibernate.hbm2ddl.auto" value="update"/>
      </util:map>
     </property> 
 </gorm:sessionFactory>
</pre>

<p>Listing NUS-3</p>

<p>Luckily, this listing isn't too complicated. Often times with Spring beans one has to define the classes being used; however, with the use of XML namespaces that is not necessary Spring is aware based on the namespace used  With that being said Listing NUS-3 serves the same purpose as your standard Hibernate definitions usually do in Spring and that is to define the Session Factory. In fact, most of the items defined will be similar to Hibernate Session Factory listings.</p>

<p>Line 1 is the name space reference to the GORM Session Factory, which is fairly standard stuff. The rest really is general Hibernate type configurations that are specific to GORM. Line 2 is used to specify where your domain objects exist.  Remember, with Hibernate you have to define your domain objects. There are basically two ways to do this: one is to define a directory full of hibernate XML mapping files, the other is to specify a directory of domain objects. Line 3, data-source-ref, references a data source that you have defined in Spring. This can be a Java Naming and Directory Interface (JNDI) data source, in memory data source or a more database specific data source. Line 4, message-source-ref, is specific to GORM itself. GORM allows one to define validation constraints in its domain, these constraints then print out messages via a message resource bundle. In Grails this message resource bundle is a predefined name and area, with GORM you will have to specify that item yourself. In GORM these validators are in a specific place with a specific name, but with Spring one can customize the location and name of this resource bundle. On line 5 we start to define the Hibernate properties.  If you were using Grails these items would be specified inside your DataSource.groovy file and if you were using JPA would be in the persistence.xml file.</p>

<h3>JAR Files Needed</h3>

<p>In addition to defining the GORM Session Factory we will also need a few of the Grails JAR files to make this work. Only three jars from Grails are needed and can be included either manually or via your Ivy/Maven configurations:</p>

<ul>
<li>grails-bootstrap 1.1</li>
<li>grails-gorm 1.1</li>
<li>grails-web 1.1</li>
</ul>      </div>
    </summary>
  </entry>
  <entry>
    <id>tag:www.integrallis.com:Article26</id>
    <published>2009-08-19T19:03:02-04:00</published>
    <updated>2009-09-08T19:07:33-04:00</updated>
    <link type="text/html" rel="alternate" href="http://www.integrallis.com/blog/2009/08/19/introducing-drools-5"/>
    <author>
      <name>Brian Sam-Bodden</name>
    </author>
    <title type="html">Introducing Drools 5</title>
    <category scheme="http://www.integrallis.com/blog/category/java" term="java" label="Java"/>
    <category scheme="http://www.integrallis.com/blog/category/jboss" term="jboss" label="JBoss"/>
    <category scheme="http://www.integrallis.com/blog/tag/drools" term="drools"/>
    <summary type="xhtml">
      <div xmlns="http://www.w3.org/1999/xhtml">
<h2>A Java Rule Engine for the rest of us</h2>

<p>For most Java developers the idea of using a Rule Engine evokes thoughts of vendors in suits selling their bosses a complex and expensive piece of software they don’t need and the introduction of something completely foreign and intrusive to their code base. Drools 5 (http://www.jboss.org/drools/) aims to change this perception by bridging the gap between the Java developer and world of Rule-based systems.
The Quick and Dirty on Rule Engines</p>

<p>The simplest explanation of what a rule engine is that is a very efficient pattern matcher. It matches data, referred to as “facts” against rules. Rules are simple if-then constructs that operate on the matched data. For example, imagine an example application in which the data is a loan application containing the credit score for the loan applicant. A rule could express a credit score requirement for a loan such as:</p>

<blockquote>
    <p>“A loan application for ACME loans for which the loan applicant has a credit score lower than 680 will be rejected”</p>
</blockquote>

<p>For the context of the this example assume that the following Java classes exist:</p>

<ul>
<li><p>Mortgage: Represents a loan product belonging to a lender. It contains amongst other data, the name of the lender providing the loan.</p></li>
<li><p>LoanApplication: Represents an application for a specific loan product. It contains information specific to the applicant such as the credit score and the lender associated with the application.</p></li>
<li><p>RejectionNotice: Represents a communication to the applicant that the application has been rejected</p></li>
</ul>

<pre class="brush: java;">
rule "LowCreditScoreRejection"
dialect "java"
    when
        mortgage:Mortgage(
            lender:lenderName == "ACME"
        )
        application:LoanApplication(
            lender == mortgage.lenderName,
            score:creditScore < 680
        )
    then
        application.reject("the score " + score + " is too low. \n" +
                           "A credit score of at least 680 is required");
        insert(new RejectionNotice(application));
end
</pre>

<p>Listing SAM-1
A simple rule</p>

<p>The rule named “LowCreditScoreRejection” is a typical Drools Rule Language (DRL) rule. It has two parts; the “when” part, also known as the “predicate”, “premise”, “condition” or simply as the “Left-hand side” (LHS for short) and the “then” part or “consequence”, “action”, “conclusion” or “Right-hand side” (RHS)</p>

<h3>The Rule Condition</h3>

<p>The “when” part or rule condition determines the patterns to be matched. That is, the types and characteristics of the objects that will activate the rule. In the example shown, we are looking to match two objects, an object of type Mortgage and an object of type LoanApplication. The “mortage” object must have a lenderName (mortgage.getLender) equals to “ACME” and the “application” must have a matching lender name and a creditScore (application.getCreditScore) that is less than 680.</p>

<p>As you can see this rule only gets evaluated if there are two objects of the aforementioned types present and it is only activated if those two objects properties match the conditions in parenthesis.</p>

<p>An observant Java developer will notice that the rule sort of looks like Java code but not quite. The when part list the classes of the objects that must be present and the values of the properties of those instances needed to activate the rule. The when part is purely a pattern matching expression using first order logic. You can think of the when part as the “where” clause in a SQL statement. Just like in a SQL statement you can create aliases for the objects being matches (and their properties). In the  “LowCreditScoreRejection” rule we have three aliases “mortgage”, “lender”, “application” and “score”. Once you have aliased a matched object that object can be used somewhere else in the rule condition and also in the rule consequence.</p>

<h3>The Rule Consequence</h3>

<p>We learned that the rule condition part of the rule determines what pattern of objects that will activate the rule. The “then” part or rule consequence is what happens when the conditions set forth in the “when” part are met. In Drools the consequence is simply a block of Java code. In the “LowCreditScoreRejection” rule example there are two things happening in the “then” part. First we are calling the “reject” method on the application and passing a message telling them why the application is being rejected (notice the use of the alias “score”). Next and last we are creating a new object of type RejectionNotice, passing the application object in the constructor and then passing the newly created object to the insert method. The insert method is a Drools working memory method that tells the rule engine that there is a new object that should be considered when evaluating the rules. In this case the expectation is that there will be another rule that has a condition expecting objects of type RejectionNotice and that will act upon them.
The Rule Engine</p>

<p>From the simple example of the “LowCreditScoreRejection” rule we see that a rule engine is a system that matches facts (our data objects) against rules. The rules are then used to infer conclusions about the data. In the example, the conclusions inferred were rejection of the loan application and the creation of the rejection notice. This type of system is what is referred to as a data-driven forward chaining reasoning system. At the heart of the system is an “inference engine”; the component that does the pattern matching, activates the rules and determines how to execute the activated rules. This process is typically referred to as truth maintenance. Under the covers Drools uses a custom version of the popular Rete algorithm (see http://en.wikipedia.org/wiki/Rete_algorithm). As we can see the “forward chaining” process starts with the available facts and uses the rules to infer more facts (such as RejectionNotice) until a desired goal as been reached (determining whether a loan application is approved or rejected and communicating the rejections).
Main Drools Classes</p>

<p>The rules like “LowCreditScoreRejection” rule are contained in DRL files (files with the extension .drl) that comply with Drools native rule language syntax. To use the created rules in a Java application you must:</p>

<ol>
<li><p>KnowledgeBuilder: A knowledge builder is the class that knows how to load and process DRL files. The impact of parsing and building in memory objects from the DRL file happens at this point. An instance of a knowledge builder can be obtained from the KnowledgeBuilderFactory using the newKnowledgeBuilder() method</p></li>
<li><p>KnowledgePackage: A knowledge package is the result of processing a DRL file; a serializable object. The knowledge builder has a getKnowledgePackages() that returns a collection of knowledge packages.</p></li>
<li><p>KnowledgeBase: A knowledge base is where the knowledge packages are deployed to so that they can be used at runtime. The knowledge base is the object that will be used to create knowledge sessions. This knowledge base is a thread safe construct that serves as a factory of sessions.</p></li>
<li><p>KnowledgeSession: The knowledge session is the object used to interact with the rule engine. It is throught a session that you will make the rule engine aware of the facts (the data) that the rule engine will evaluate against the available rules.
Inside the Rule Engine</p></li>
</ol>

<p>Inside the rule engine, after you have inserted your facts into a knowledge session and invoked the session fireAllRules() method:</p>

<ol>
<li><p>Rules are matched against the facts in the knowledge session using the pattern matcher (Rete algorithm)</p></li>
<li><p>The unordered list of activations (the Rules that apply based on the facts) is ordered internally (by a conflict resolver) in the session’s agenda</p></li>
<li><p>The first Rule in the agenda is the executed, possibly triggering steps 1 and 2 again</p></li>
</ol>

<p>This loop is how a Rule Engine infers knowledge from existing facts using rules. You can see that a Rule Engine using pattern matching to reduce/transform the problem space to arrive at a set of facts that can be considered a solution to the problem at hand.
Getting Started with Drools 5: Classifying you Twitter network</p>

<p>Rule Engine development introduces enough conceptual complexity (mainly inherited from the A.I. lingo and academia) that feels fairly unapproachable us Java developers. So, let tackle a simple but yet representative problem using Drools 5.</p>      </div>
    </summary>
  </entry>
  <entry>
    <id>tag:www.integrallis.com:Article25</id>
    <published>2009-03-03T20:44:40-05:00</published>
    <updated>2009-09-08T23:54:59-04:00</updated>
    <link type="text/html" rel="alternate" href="http://www.integrallis.com/blog/2009/03/03/jsecurity-permissions-in-grails"/>
    <author>
      <name>Joseph Nusairat</name>
    </author>
    <title type="html">JSecurity Permissions in Grails</title>
    <category scheme="http://www.integrallis.com/blog/category/groovy-grails" term="groovy-grails" label="Groovy"/>
    <category scheme="http://www.integrallis.com/blog/category/grails" term="grails" label="Grails"/>
    <category scheme="http://www.integrallis.com/blog/tag/grails" term="Grails"/>
    <category scheme="http://www.integrallis.com/blog/tag/security" term="Security"/>
    <summary type="xhtml">
      <div xmlns="http://www.w3.org/1999/xhtml">
<p>One of the security plugins I have looked at with the most interest is the JSecurity plugin. I was attracted to the JSecurity because it seemed to provide a good mix of out of the box support but also being flexible enough for customizations.</p>

<p>On the surface JSecurity provides much of the normal security you'd expect from any framework. There is out of the box support for login/logout authentication, support for role based lock downs, and finally even the ability to create permission based security. It's the last one I wanted to write about.</p>

<p>Understanding how to do normal authentication with JSecurity and implementing roles is pretty straight forward and the documentation on the grails wiki found <a href="http://www.grails.org/JSecurity+Plugin+-+Quick+Start">here</a>. Where I believe the documentation lacks a bit on is using permissions. That being said, the documentation on the wiki is very good at understanding WHAT permissions are and creating custom ones but not necessarily how to create basic ones in the first place.</p>

<p>I am going to assume you have all used JSecurity or can go to the previous URL and read about it and will discuss implementing permissions for JSecurity. Sometimes knowing when to use permissions can be rather complex. And sometimes justifiably so, the way to use permissions (and of course there are many ways to use them) is when you keep needing to fine tune access to a particular source on a per user basis. Take a typical web application with a user list. We may want to allow someone to have read access to the list, another to have read and write, and another to have read, write, delete. To perform this check with roles we would basically have to have 3 different roles and assign them when needed. The problem with this solution is it basically gets messy fast especially if you have quite a bit of resources you want to lock down in this way. Permissions are designed to solve this problem exactly, by allowing a finer grain access on a resource. Let's dive into how to create permissions in JSecurity.</p>

<p>How do we perform this in Grails with JSecurity? JSecurity essentially has three tables that handle permissioning: JsecPermission, JsecUSerPermissionRel, and JsecUserRoleRel. We will look at how these tables are going to help us create and lock down pages on a per user basis.</p>

<p>Let's first discuss how JSecurity interprets permisssions to begin with. JSecurity permission is more complex than some because it does not force one to treat every resource (ie: web page, file system, specific part of the app) equally. JSecurity allows you to define what the permission resource IS in the first place. For example the permission logic for a web URL like our in example of a user page, to-do page, etc would differ from a file resource if you were creating a documentation management site. The wiki for the JSecurity shows examples of a FilePermission or a ProjectPermission, anything that implements the Permission interface. Each of these classes will have an implies() methods that actually determines HOW one is to interpret the permission. This is great because it gives the user the maximum flexibilty in determining how they want there permission applied. Now while i say that is great, let's face it most of us are going to use permissions for as I described above in Grails, to lock down a particular controller / action. The good news is out of the box Grails JSecurity plugin provides a specialized permission for controller based security. They have what is called a basic permission 'org.jsecurity.grails.JsecBasicPermission'. This permission is good for when you want to apply the concept of controller / action security. And it is this particular use case I am going to show how to use below.</p>

<p>To start with even though we have the permission as a resource on the class path its name needs to be stored to the database so the system can do reflection on it later. The first table we need to add to is the JsecPermission table. This table is simply going to keep a list of all the permission classes we have and the possible actions for each. So for our controller / action lockdowns we will simply add a reference to the JsecBasicPermission into the database:</p>

<h3>Creating the Database Permission</h3>

<pre class="brush: groovy;">
def perm = new JsecPermission(type: 'org.jsecurity.grails.JsecBasicPermission', possibleActions: '*').save() 
</pre>

<p>Now as you have noticed i have used an * for the possible actions, this is more to fill in the blanks than for anything useful. By default with the JsecBasePermission it really does not care about the actions used here. Now just because this particular permission is not using possible actions does not mean that another permission in the future could use it nor does it mean it HAS to use it either. This is part of JSecurity's methodology of trying to keep maximum flexibility.</p>

<p>Assigning the User to the Permissions
Now that we created the permission let's assign it to a user you have already created. To assign it you basically have two choices. Either assign it to a role or assign the permission directly to the user. I am going to do the latter and assign it to the user. In the following code we are taking our user and our permission and allowing the actions of delete and edit.</p>

<pre class="brush: groovy;">
new JsecUserPermissionRel(
    user : user,  
    permission: perm, 
    target : 'user', 
    actions : 'delete, edit').save() 
</pre>

<h3>Locking Down the Resource</h3>

<p>So now that we have the permission we are going to lock down the security for the controller, and here is where it may get a bit tricky to understand. First off remember we have not done any permissioning for create or list, so by default we do not want to do any permissioning check for those because we have not assigned any. So in our filter lets add two permissioning interceptors for delete and edit only:</p>

<pre class="brush: groovy;">
user(controller: &quot;register&quot;, action: &quot;delete&quot;) {      
    before = { 
        accessControl { 
            permission(type: 'user', actions: actionName)
        }      
    } 
}  

user(controller: &quot;register&quot;, action: &quot;edit&quot;) {      
    before = {
        accessControl { 
            permission(type: 'user', actions: actionName) 
        }      
    } 
} 
</pre>

<p>Now the application will check for permissions with edit and delete only, and unless you are assigned will take you to a page saying that you aren't allowed.</p>

<p>Now where I said it can get confusing is the naming as you go through, and this is where we harp back to saying that the permissions in JSecurity is very much user based. While this provides a huge degree of flexibility it can also cause naming you thought should go together not always go together. So take where we initially defined type in the JsecPermission table. This type was our fully qualified class type. However, the type down in the filter we define has nothing to do with the JsecPermission type. This type is instead going to relate to the target we defined in JsecUserPermissionRel. This is an important distinction to make, and one that confused me at first when using the JsecBasicPermission. The actions part, that is more self explanatory and the actions you pass in will be the actions that it will check against.</p>      </div>
    </summary>
  </entry>
  <entry>
    <id>tag:www.integrallis.com:Article22</id>
    <published>2007-12-26T12:59:47-05:00</published>
    <updated>2009-09-08T19:34:41-04:00</updated>
    <link type="text/html" rel="alternate" href="http://www.integrallis.com/blog/2008/01/15/building-tempo-with-rails-part-vi"/>
    <author>
      <name>Brian Sam-Bodden</name>
    </author>
    <title type="html">Building Tempo with Rails, Part VI</title>
    <category scheme="http://www.integrallis.com/blog/category/ruby" term="ruby" label="Ruby"/>
    <category scheme="http://www.integrallis.com/blog/category/rails" term="rails" label="Rails"/>
    <category scheme="http://www.integrallis.com/blog/tag/rails" term="Rails"/>
    <category scheme="http://www.integrallis.com/blog/tag/ruby" term="Ruby"/>
    <category scheme="http://www.integrallis.com/blog/tag/agile" term="agile"/>
    <summary type="xhtml">
      <div xmlns="http://www.w3.org/1999/xhtml">
<p><img src="/blog/files/rails.png" alt="Rails"/></p>

<p>In this installment we are going to build the Dashboard page of the Tempo application. The first incarnation of the Dashboard page will serve as the entry point/main page of the application and its main function will be to provide an interface for users to report time against a project-activity combination.</p>

<p>The user story that we are targeting is:</p>

<p>TMPO-29: “User enters Time” Business Critical [OPEN] 40 points 0% unassigned</p>

<p>The description above is from the Agile Project Management and Collaboration tool <a href="http://www.caimito.net/">Caimito One</a>. The “User enters Time” story is business critical, it is still OPEN, we have estimated 40 complexity points to it, is 0% completed and it has not been assigned to any team member (or no team member has volunteered for it!)</p>

<p>The description of the user story is "As a User I would like to enter time against a project and activity by providing a starting and ending time"</p>

<h1>User Interface</h1>

<p>Based on the story description I’ve come up with a rough sketch of what I picture the Dashboard page looking like after the first pass:</p>

<p><img src="/blog/files/tempo_dashboard_sketch.png" alt="tempo dashboard sketch"/></p>

<p>The sketch above shows 3 different areas:</p>

<ul>
<li><em>Date Selection</em>: A Calendar-style component that will enable the user to select a given (active) date to enter time</li>
<li><em>Time Entry Details</em>: A form that will provide drop-downs for the Project, Activity, Start Time, End Time for the TimeEntry as well as a text area for a description. Optionally the user will be allowed to enter time as a number of hours to be reported against the given date (with no specific start or end times(1)).</li>
<li><em>Daily Summary</em>: A table displaying the time entries reported for the active date.</li>
</ul>

<p>(1) Notice that I’ve just created a new requirement that was not present in the original User Story. 
In our work to fulfill the main User Story we will set the stage to satisfy this new requirement but we should really create a new issue (story) to tackle that new piece of functionality (of course first we should check with the project owner and/or stakeholders)</p>

<h1>Dashboard Controller</h1>

<p>I started by creating the skeleton code and tests for the Dashboard Controller:</p>

<pre class="brush: shell;">
script/generate rspec_controller dashboard   
      exists  app/controllers/
      exists  app/helpers/
      create  app/views/dashboard
      exists  spec/controllers/
      exists  spec/helpers/
      create  spec/views/dashboard
      create  spec/controllers/dashboard_controller_spec.rb
      create  spec/helpers/dashboard_helper_spec.rb
      create  app/controllers/dashboard_controller.rb
      create  app/helpers/dashboard_helper.rb
</pre>

<p>Since we want the dashboard to be the default page for our application we can modify the config/routes.rb accordingly:</p>

<pre class="brush: ruby;">
map.connect '', :controller => "dashboard", :action => "index"
</pre>

<p>With the skeleton in place I can now do a little planning about what I need to build.</p>

<h1>A bit of Design</h1>

<p>Here's what I know about the Dashboard page so far:</p>

<ol>
<li>The Dashboard page can only be shown if there is a user logged in. (done, taken care by the restful authentication plug-in)</li>
<li>When the user first navigates to the Dashboard page, the current date should be shown in the calendar date picker and on the “blog” style display on the time entry form</li>
<li>The Daily Work table should show all TimeEntries for the current user for the selected date</li>
<li>When the user selects a new date form the calendar date picker the "current date" (the date which under the times entered will be reported) should change.</li>
</ol>

<h1>Create the Views</h1>

<p>Let’s start by creating an index.rhtml template in the Views/dashboard directory. The index template will render three partials; one for a blog-style date, the TimeEntry form and one for the Daily Work table. The partials will be _current_date.rhtml, _form.rhtml and _time_entries.rhtml respectively.</p>

<h3>views/dashboard/index.rhtml</h3>

<p>The listing below shows the contents for index.rhtml. I used some of the CSS styles provided by ActiveScaffold to keep the look and feel consistent.</p>

<pre class="brush: ruby;">
<div class="active-scaffold">
  <div class="create-view view">  
    <% form_tag :action => 'create' do %>
      <h4><div id="current_date_div"><%= render :partial => "current_date" %></div></h4>
      <ol class="form" >
        <%= render :partial => 'form' %>
        <p class="form-footer">
          <%= submit_tag "Create" %>
        </p>
      </ol>
    <% end %>
  </div>
</div>

<br />
<p>
<div id="time_entries_div">
  <%= render :partial => "time_entries" %>
</div>
</p>    
</pre>

<p>The index.rhtml view renders a form (which body is contained in the _form.rhtml partial), the current date which is render by the partial _current_date.rhtml. Finally at the bottom we have a section that contains the daily work table summary which is rendered by the _time_entries.rhtml partial. Let's take a look at each one of those partials next:</p>

<h3>views/dashboard/_current_date.rhtml</h3>

<p>The idea here is to render a blog style data block as shown below:</p>

<p><img src="/blog/files/tempo_dashboard_date_block.png" alt="tempo dashboard sketch"/></p>

<p>To render the blog style date I have a CSS snippet that I use to style a partial containing the current date. The partial _current_date.rhtml is shown below:</p>

<pre class="brush: ruby;">
<div class="dateblock">
  <div class="dateblock_month">
    <%= "#{Time::RFC2822_MONTH_NAME[@current_date.month-1]}" %>
  </div>
  <div class="dateblock_day">
    <%= "#{@current_date.day}" %>
  </div>
  <div class="dateblock_year">
    <%= "#{@current_date.year}" %>
  </div>
</div>
</pre>

<p>Notice that I use an instance variable current_date that will be set in the index method of the dashboard controller if it cannot be retrieved from the session:</p>

<pre class="brush: ruby;">
  def index
    unless session[:current_date] 
      session[:current_date] = Time.today  
    end
    @current_date = session[:current_date]
  end
</pre>

<p>In the controller the method to render the partial and update the instance and the session variable follows:</p>

<pre class="brush: ruby;">
  def current_date
    session[:current_date] = Time.parse(params[:current_date])
    @current_date = session[:current_date]
    render :partial => 'current_date'
  end
</pre>

<p>The CSS code for the dateblock is shown below (I've found it on a CSS site but I can't remember where):</p>

<pre class="brush: ruby;">
/*-------------------------------------------------
DATE BLOCK
-------------------------------------------------*/
.dateblock {
  text-align: center;
  width: 50px;
  font-family: sans-serif;
  border: solid 1px black;
  padding-top: 5px;
  color: white;
  background-color:black;
  margin-top: 10px;
  margin-bottom: 10px;
  line-height: 1.22em;
  font-family: sans-serif;
}

.dateblock_month {
  font-size: 12px;
}

.dateblock_day {
  font-size: 26px;
  position: relative;
  top: -2px; 
}

.dateblock_year {
  font-size: 12px;
  position: relative;
  top: -2px;
}
</pre>

<h3>views/_time_entries.rhtml</h3>

<p>For the Daily Work table showing all TimeEntries for the current user for the selected date we use the _time_entries.rhtml partial. This partial makes use of ActiveScaffold's ability to embed a scaffold in another controller, or view. To accomplish this we use the <pre class="brush: ruby;">render :active<em>scaffold => 'time</em>entries'</pre> which will call the render_component passing a specific set of conditions (to be appended to the SQL select statement) and a custom label for the scaffold table:</p>

<pre class="brush: ruby;">

<%= render :active_scaffold => 'time_entries', 
           :conditions => 
             ["user_id = ? AND YEAR(start) = ? AND MONTH(start) = ? AND DAY(start) = ?",
              @current_user.id, @current_date.year, @current_date.month, @current_date.mday], 
           :label => 
             "Time Entries for #{Time::RFC2822_DAY_NAME[@current_date.wday]}, #{Time::RFC2822_MONTH_NAME[@current_date.month-1]} #{@current_date.day} #{@current_date.year}" %>
</pre>

<p>In the controller we need to modify the index method to also filter the collection of TimeEntry objects retrieved:</p>

<pre class="brush: ruby;">
  def index
    unless session[:current_date] 
      session[:current_date] = Time.today  
    end
    @current_date = session[:current_date]
    @time_entries = TimeEntry.find(:all, :conditions => ["user_id = ? AND YEAR(start) = ? AND MONTH(start) = ? AND DAY(start) = ?", @current_user.id, @current_date.year, @current_date.month, @current_date.mday])
  end
</pre>

<p>We also need a time_entries method to render the TimeEntry(s) based on the current_date in the session:</p>

<pre class="brush: ruby;">
  def time_entries
    session[:current_date] = Time.parse(params[:current_date])
    @current_date = session[:current_date]
    render :partial => 'time_entries'
  end
</pre>

<p>The daily work table should now display all the TimeEntry(s) for the current/selected date:</p>

<p><img src="/blog/files/tempo_dashboard_closeup.png" alt="tempo dashboard sketch"/></p>      </div>
    </summary>
  </entry>
  <entry>
    <id>tag:www.integrallis.com:Article19</id>
    <published>2007-12-06T20:36:09-05:00</published>
    <updated>2009-09-08T19:31:19-04:00</updated>
    <link type="text/html" rel="alternate" href="http://www.integrallis.com/blog/2007/12/06/building-tempo-with-rails-part-v"/>
    <author>
      <name>Brian Sam-Bodden</name>
    </author>
    <title type="html">Building Tempo with Rails, Part V</title>
    <category scheme="http://www.integrallis.com/blog/category/ruby" term="ruby" label="Ruby"/>
    <category scheme="http://www.integrallis.com/blog/category/rails" term="rails" label="Rails"/>
    <category scheme="http://www.integrallis.com/blog/tag/rails" term="Rails"/>
    <category scheme="http://www.integrallis.com/blog/tag/ruby" term="Ruby"/>
    <category scheme="http://www.integrallis.com/blog/tag/agile" term="agile"/>
    <summary type="xhtml">
      <div xmlns="http://www.w3.org/1999/xhtml">
<p><img src="/blog/files/rails.png" alt="Rails"/></p>

<p>This installment was supposed to be about building the Dashboard page of the Tempo application. Instead, I'm addressing some bugs reported by readers.</p>

<h2>Fixing Bugs TDD-style</h2>

<p>An observant reader pointed out that one of the tests for the TimeEntry class broke when testing using a date range across a month boundary.</p>

<p>The offending code is shown below:</p>

<pre class="brush: ruby;">
  def split!
    remaining_time_entries = []
    if needs_splitting
      # save the original end time
      original_end = self.end 
      # first change the current TimeEntry to the end_of_day of the start day
      self.end = self.start.change(:hour => 23, :min => 59, :sec => 59)
      (self.start.day+1..original_end.day).each do |day|
        time_entry = self.clone
        time_entry.start = time_entry.start.change(:mday => day).beginning_of_day
        if day == original_end.day
          time_entry.end = original_end
        else
          time_entry.end = time_entry.start.change(:hour => 23, :min => 59, :sec => 59)
        end
        remaining_time_entries << time_entry
      end   
    end
    remaining_time_entries
  end
</pre>

<p>Even though the code above was created in a TDD fashion and several of the tests created exercised the code, the tests failed to cover all of the possible cases.</p>

<p>The lesson here is that when dealing with date ranges, you should test across months and year boundaries. The code above only works when the two datetimes are in the same month and year which is a critical flaw. The code uses the day method to loop form the start day to the end day of the range.  This will obviously break across months and of course across years.</p>

<p>One good thing about the test above was (as some might argue whether this is a good thing or not) is that I used a date range that started on the current date and time. In a continuous integration scenario this broken test would had revealed itself in the hourly build.</p>

<p>I've also made the same mistake (of using the day method) to check if a range of dates needed splitting, here's the original code:</p>

<pre class="brush: ruby;">
def needs_splitting
  self.start.day < self.end.day
end
</pre>

<p>First, let's prove that the code is indeed broken. To accomplish this I've written a test that crosses a month boundary:</p>

<pre class="brush: ruby;">
it "should know how to split a time entry across multiple days over a month boundary" do
  time_entry = create_time_entry
  time_entry.start = Time.local(2007,"nov",30,23,0,0)
  time_entry.end = 5.hours.since(time_entry.start)
  entries = time_entry.split!
  entries.should_not be_empty
  total = 0.0
  entries.inject(0) {|total, e| total += e.total_hours}
  total += time_entry.total_hours
  total.should eql(5.0)
  time_entry.needs_splitting.should_not be_true
end
</pre>

<p>The above test fails with the existing code. Now we can refactor the code to pass the test. </p>

<pre class="brush: ruby;">
  def needs_splitting    
    (self.start.year != self.end.year) ||
    (self.start.month != self.end.month) ||
    (self.start.day != self.end.day) 
  end

  def split!
    remaining_time_entries = []
    if needs_splitting
      # save the original end time
      original_end = self.end 
      # first change the current TimeEntry to the end_of_day of the start day
      self.end = end_of_day(self.start)
      days = ((original_end - self.start) / 86400).ceil.to_i  
      (1..days).each do |day|
        time_entry = self.clone
        time_entry.start = time_entry.start.advance(:days => day).beginning_of_day
        time_entry.end = time_entry.end.advance(:days => day)
        if same_day(time_entry.end, original_end)
          time_entry.end = time_entry.end.change(:hour => original_end.hour, :min => original_end.min, :sec => original_end.sec)   
        else
          time_entry.end = end_of_day(time_entry.start)
        end
        remaining_time_entries << time_entry
      end   
    end
    remaining_time_entries
  end
</pre>

<p>The needs_splitting method now checks the year, month and day. The split! method now finds the total number of whole days (plus one) in the datetime range. It then creates new TimeEntry(s) for each of the whole days (24 hours each) and a partial one of the last day on the range. To advance each one of the days I use the advance method (see Rails extensions to the Time class).</p>      </div>
    </summary>
  </entry>
  <entry>
    <id>tag:www.integrallis.com:Article18</id>
    <published>2007-11-12T09:45:27-05:00</published>
    <updated>2009-09-08T19:29:56-04:00</updated>
    <link type="text/html" rel="alternate" href="http://www.integrallis.com/blog/2007/11/30/building-tempo-with-rails-part-iv"/>
    <author>
      <name>Brian Sam-Bodden</name>
    </author>
    <title type="html">Building Tempo with Rails, Part IV</title>
    <category scheme="http://www.integrallis.com/blog/category/ruby" term="ruby" label="Ruby"/>
    <category scheme="http://www.integrallis.com/blog/category/rails" term="rails" label="Rails"/>
    <category scheme="http://www.integrallis.com/blog/tag/rails" term="Rails"/>
    <category scheme="http://www.integrallis.com/blog/tag/ruby" term="Ruby"/>
    <category scheme="http://www.integrallis.com/blog/tag/agile" term="agile"/>
    <with_options length="113626">
      <link type="applicaton/octet-stream" rel="enclosure" href="http://www.integrallis.com/blog/files/tempo_public1.zip" title="Building Tempo with Rails, Part IV"/>
    </with_options>
    <summary type="xhtml">
      <div xmlns="http://www.w3.org/1999/xhtml">
<p><img src="/blog/files/rails.png" alt="Rails"/></p>

<p>In the last three installments of this series we concentrated our efforts on building the most important entities of the Tempo domain. If you are anything like me you need visual feedback to truly get a sense of progress, if anything for the psychological effect of seeing something working (other than on the command line)</p>

<p>Before we jump into building the visual aspects of the application we should finish configuring the restful_authentication system we installed in installment #1. </p>

<h1>Configuring Restful Authentication </h1>

<p>The first step is to protect all controllers in our application by applying a before filter that will trigger the authentication logic. In Rails the ApplicationController is the ideal place to do so since is the default parent class for all controllers in an application:</p>

<pre class="brush: ruby;">
class ApplicationController < ActionController::Base
  include AuthenticatedSystem

  session :session_key => '_tempo_session_id'

  before_filter :login_required
end
</pre>

<p>In the file application.rb we include the AuthenticatedSystem and apply the before filter :login_required which will cascade down to any new controllers we create. </p>

<p>The restful_authentication plugin creates two controllers, the UsersController; a typical CRUD controller for User objects and the SessionsController which is the controller responsible the login/session management logic.</p>

<p>Taking a peek at the Session controller we see that it is set to skip the :login_required filter:</p>

<pre class="brush: ruby;">
class SessionsController < ApplicationController

  skip_before_filter :login_required

  ...

end
</pre>

<p>In the Views/sessions directory we customize the new session view (a.k.a the login screen):</p>

<pre class="brush: ruby;">
<div class="login">
  <div id="Dialog">
    <h1>Welcome to Tempo, please log in</h1>
    <dl>
      <% form_tag session_path do -%>
        <dt>Username:</dt>
        <dd><%= text_field_tag 'login' %></dd>

        <dt>Password:</dt>
        <dd>
          <%= password_field_tag 'password' %>
          <span>(<a href="/forgot_password">I forgot my password/username</a>)</span>
        </dd>

        <dd><%= check_box_tag 'remember_me' %>Remember me on this computer</dd>

        <dd><%= submit_tag 'Log in' %></dd>
      <% end -%>
    </dl>
  </div>
</div>
</pre>

<h1>Permanent Scaffolding?</h1>

<p>To give us a jump start in the right direction I'm going to make use of a Rails scaffolding plug-in that should allow us to get some fairly decent web pages up and running in no time. There seems to be two contenders in the area of "permanent" Rails scaffolding plugins, one is the <a href="http://streamlinedframework.org/">Streamlined Framework</a> produced by the brilliant folks at <a href="http://relevancellc.com">Relevance</a> the other one is <a href="http://www.activescaffold.com">ActiveScaffold</a> created by the same team that built the now deprecated <a href="http://www.ajaxscaffold.com/">AjaxScaffold</a>. </p>

<p>Both frameworks attempt to provide you with a way to generate ActiveRecord-driven scaffolding screens that are configurable and flexible enough that you theoretically won't have to later tear them down to build the "real" pages of you application. I've briefly looked at both frameworks previously and they both seem fairly even in terms of features. So just for the sake of trying something new I'm gonna use ActiveScaffold for the Tempo time tracking application.</p>

<h1>ActiveScaffold</h1>

<p>The ActiveScaffold website has quite a bit of documentation that should help you get started. I in particular found their <a href="http://www.activescaffold.com/tutorials/how-to-approach-active-scaffold">"How to Approach Active Scaffold"</a> article useful in understanding where it would be a good idea to use the framework.</p>

<p>To get started with ActiveScaffold in the Tempo project you'll need to first install the plug-in using Piston:</p>

<pre class="brush: shell;">
piston import http://activescaffold.googlecode.com/svn/tags/active_scaffold vendor/plugins/active_scaffold
Exported r633 from 'http://activescaffold.googlecode.com/svn/tags/active_scaffold' to 'vendor/plugins/active_scaffold'
</pre>

<p>Once you have installed the plug-in all that you need to do to enable the scaffolding for one of you model objects is to add a minimal amount of code to your controllers:</p>

<pre class="brush: ruby;">
class UsersController < ApplicationController 
  active_scaffold :user
end
</pre>

<p>In your application layout head section you also need to include:</p>

<pre class="brush: ruby;">
<%= javascript_include_tag :defaults %>
<%= active_scaffold_includes %>
</pre>

<p>That will give you the basic ActiveScaffold CRUD functionality.</p>      </div>
    </summary>
  </entry>
  <entry>
    <id>tag:www.integrallis.com:Article17</id>
    <published>2007-10-31T12:21:41-04:00</published>
    <updated>2009-09-08T19:24:54-04:00</updated>
    <link type="text/html" rel="alternate" href="http://www.integrallis.com/blog/2007/10/31/building-tempo-with-rails-part-iii"/>
    <author>
      <name>Brian Sam-Bodden</name>
    </author>
    <title type="html">Building Tempo with Rails, Part III</title>
    <category scheme="http://www.integrallis.com/blog/category/ruby" term="ruby" label="Ruby"/>
    <category scheme="http://www.integrallis.com/blog/category/rails" term="rails" label="Rails"/>
    <category scheme="http://www.integrallis.com/blog/tag/rails" term="Rails"/>
    <category scheme="http://www.integrallis.com/blog/tag/ruby" term="Ruby"/>
    <category scheme="http://www.integrallis.com/blog/tag/agile" term="agile"/>
    <summary type="xhtml">
      <div xmlns="http://www.w3.org/1999/xhtml">
<p><img src="/ourblogs/files/rails.png" alt="Rails"/></p>

<p>Now that we have a basic understanding of BDD with RSpec let's pick a business 
critical user story and build it from tests outwards. With Tempo being a time tracking system 
the most crucial story should be a "User enters Time".</p>

<h2>TimeEntry</h2>

<p>At the core of this story is the model class TimeEntry. In Tempo we want users to be able to
enter time by:</p>

<ul>
<li>a) picking a beginning time an an end time for a given date</li>
<li>b) picking a beginning date-time and an end date-time</li>
</ul>

<p>For billing purposes it is usually convenient to split the hours in a range of date-times into 
chunks of hours per day (for the ranges that span over multiple days). The way I envision these
two entry methods are:</p>

<ul>
<li>a) a simple page that defaults to the current date and that allows the user to pick two
times for the given day along with other information required (project, activity, etc.)</li>
<li>b) a page with two date/time pickers that enables the user to pick a range (or some fancier
UI control if I can find one)</li>
</ul>

<p>In the spirit of TDD let's start with the skeleton RSpec specification for TimeEntry. 
In the spec/models directory of the application create the Ruby file time_entry_spec.rb:</p>

<pre class="brush: ruby;">
describe TimeEntry do

  before do
    @time_entry = TimeEntry.new
  end

  it "should be invalid without an associated User" do
  end

  it "should be invalid without an associated Project" do
  end

  it "should be invalid without an associated Project Activity" do
  end

  it "should know that it needs to be split across days" do
  end

  it "should know how to split a time entry across multiple days" do
  end

  it "should not have a value higher than 24 hours" do
  end

end
</pre>

<p>Notice that I've added an expectation that a given time entry should know that it
needs to be split across multiple days and it also should know how to perform this split.</p>

<p>If I run the tests now they should obviously fail. We don't even have a TimeEntry class in place:</p>

<pre class="brush: shell;">
rake spec
(in /Users/bsbodden/Documents/projects/tempo)
/.../lib/active_support/dependencies.rb:266:in `load_missing_constant': uninitialized constant TimeEntry (NameError)
</pre> 

<p>Let's get pass that one problem and create the model:</p>

<pre class="brush: shell;">
script/generate rspec_model TimeEntry
      exists  app/models/
      exists  spec/models/
      exists  spec/fixtures/
      create  app/models/time_entry.rb
      create  spec/fixtures/time_entries.yml
overwrite spec/models/time_entry_spec.rb? [Ynaqd] n
        skip  spec/models/time_entry_spec.rb
      exists  db/migrate
      create  db/migrate/004_create_time_entries.rb
/> 
</pre> 

<p>Notice that the generate task will try to overwrite the spec we just wrote so answer NO (n) to the overwrite question as shown above.
Let's add the basic fields we would expect to find in our TimeEntry class/table:</p>

<pre class="brush: ruby;">
class CreateTimeEntries < ActiveRecord::Migration
  def self.up
    create_table :time_entries do |t|
      t.column :user_id, :integer
      t.column :project_id, :integer 
      t.column :projects_activity_id, :integer
      t.column :start, :datetime
      t.column :end, :datetime
      t.column :hours, :float
      t.column :comment, :string 
    end
  end

  def self.down
    drop_table :time_entries
  end
end
</pre>

<p>Run the migration to get the table created:</p>

<pre class="brush: shell;">
rake db:migrate
(in /Users/bsbodden/Documents/projects/tempo)
== CreateTimeEntries: migrating ===============================================
-- create_table(:time_entries)
   -> 0.0414s
== CreateTimeEntries: migrated (0.0416s) ======================================
</pre> 

<p>If we run the tests, they all pass now, that's not good, not quite TDD, so let's add some substance and break things as they should:</p>

<p>Let's start with the easy stuff:</p>

<pre class="brush: ruby;">
  before do
    @time_entry = TimeEntry.new
    @user = User.new
  end

  it "should be invalid without an associated User" do
    @time_entry.should_not be_valid
    @time_entry.errors.on(:user).should eql("must have an associated user")
    @time_entry.user = @user
    @time_entry.should be_valid
  end 
</pre>

<p>Run the tests again and we now have our first 'expected' failure:</p>

<pre class="brush: shell;">
1)
'TimeEntry should be invalid without an associated User' FAILED
expected valid? to return false, got true
./spec/models/time_entry_spec.rb:14:

Finished in 0.06691 seconds

8 examples, 1 failure
</pre> 

<p>As we learned in part II, to pass this test we need a one liner to add an ActiveRecord validation:</p>

<pre class="brush: ruby;">
class TimeEntry < ActiveRecord::Base
  has_one :user

  validates_presence_of :user, :message => 'must have an associated user'
end
</pre>

<p>Test again to confirm that the validation test passes:</p>

<pre class="brush: shell;">
rake spec
(in /Users/bsbodden/Documents/projects/tempo)
........

Finished in 0.071294 seconds

8 examples, 0 failures
</pre> 

<p>Next one down the line is the test for an associated project:</p>

<pre class="brush: ruby;">
  before do
    @time_entry = TimeEntry.new
    @user = User.new
    @project = Project.new
  end

  it "should be invalid without an associated Project" do
    @time_entry.should_not be_valid
    @time_entry.errors.on(:project).should eql('must have an associated project')
    @time_entry.project = @project
    @time_entry.should be_valid
  end
</pre>

<p>Running the test again should confirm that we do not have a Project model yet:</p>

<pre class="brush: shell;">
rake spec
(in /Users/bsbodden/Documents/projects/tempo)
..FFFFFF

1)
NameError in 'TimeEntry should not have a value higher than 24 hours if expressed as a single hour value'
uninitialized constant Project
./spec/models/time_entry_spec.rb:12:

2)
NameError in 'TimeEntry should be broken into two or more TimeEntry instances if it date-time range spans over multiple days'
uninitialized constant Project
./spec/models/time_entry_spec.rb:12:

3)
NameError in 'TimeEntry should either consist of a date-time range or a single hour value'
uninitialized constant Project
./spec/models/time_entry_spec.rb:12:

4)
NameError in 'TimeEntry should be invalid without an associated Project Activity'
uninitialized constant Project
./spec/models/time_entry_spec.rb:12:

5)
NameError in 'TimeEntry should be invalid without an associated Project'
uninitialized constant Project
./spec/models/time_entry_spec.rb:12:

6)
NameError in 'TimeEntry should be invalid without an associated User'
uninitialized constant Project
./spec/models/time_entry_spec.rb:12:

Finished in 0.121636 seconds

8 examples, 6 failures
</pre> 

<p>Add the Project model to the mix using the rake task:</p>

<pre class="brush: shell;">
script/generate rspec_model Project  
      exists  app/models/
      exists  spec/models/
      exists  spec/fixtures/
      create  app/models/project.rb
      create  spec/fixtures/projects.yml
      create  spec/models/project_spec.rb
      exists  db/migrate
      create  db/migrate/005_create_projects.rb
</pre> 

<p>Modify the migration to add the basic fields expected in a Project:</p>

<pre class="brush: ruby;">
class CreateProjects < ActiveRecord::Migration
  def self.up
    create_table :projects do |t|
      t.column :name, :string
      t.column :description, :string
      t.column :owner_id, :integer
    end
  end

  def self.down
    drop_table :projects
  end
end
</pre>

<p>and run the migration:</p>

<pre class="brush: shell;">
rake db:migrate
(in /Users/bsbodden/Documents/projects/tempo)
== CreateProjects: migrating ==================================================
-- create_table(:projects)
   -> 0.0377s
== CreateProjects: migrated (0.0380s) =========================================
</pre> 

<p>Let's test again with the Project model in place:</p>

<pre class="brush: shell;">
/> rake spec
(in /Users/bsbodden/Documents/projects/tempo)
......F..

1)
'TimeEntry should be invalid without an associated Project' FAILED
expected "must have an associated project", got nil (using .eql?)
./spec/models/time_entry_spec.rb:24:

Finished in 0.081038 seconds

9 examples, 1 failure
</pre> 

<p>Great, now we broke what we wanted to break ;-)</p>

<p>Let's now add the validations for project:</p>

<pre class="brush: ruby;">
class TimeEntry < ActiveRecord::Base
  has_one :user
  has_one :project

  validates_presence_of :user, :message => 'must have an associated user'
  validates_presence_of :project, :message => 'must have an associated project'
end
</pre>

<p>Let's test one more time:</p>

<pre class="brush: shell;">
rake spec
(in /Users/bsbodden/Documents/projects/tempo)
......FF.

1)
'TimeEntry should be invalid without an associated Project' FAILED
expected valid? to return true, got false
./spec/models/time_entry_spec.rb:26:

2)
'TimeEntry should be invalid without an associated User' FAILED
expected valid? to return true, got false
./spec/models/time_entry_spec.rb:19:

Finished in 0.083707 seconds

9 examples, 2 failures
</pre> 

<p>Let's fix our problems by adding a module with a helper create method for TimeEntries and we'll just nil the associations that 
we are looking to test: </p>

<pre class="brush: ruby;">
module TimeEntrySpecHelperMethods
  def create_time_entry(options = {})
    @user = User.new
    @project = Project.new
    TimeEntry.create({ :user => @user, :project => @project }.merge(options))
  end
end

describe TimeEntry do

  include TimeEntrySpecHelperMethods

  it "should be invalid without an associated User" do
    time_entry = create_time_entry(:user => nil)
    time_entry.should_not be_valid
    time_entry.errors.on(:user).should eql('must have an associated user')
    time_entry.user = @user
    time_entry.should be_valid
  end

  it "should be invalid without an associated Project" do
    time_entry = create_time_entry(:project => nil)
    time_entry.should_not be_valid
    time_entry.errors.on(:project).should eql('must have an associated project')
    time_entry.project = @project
    time_entry.should be_valid
  end
</pre>

<h3>Pending Tests in RSpec</h3>

<p>What do you know! it always helps to have an expert near by, Joe O'brien from the 
<a href="http://www.theedgecase.com">EdgeCase</a> just stopped by and schooled me on some of 
the subtleties of RSpec. 
If you remember I started with a skeleton for a test that was passing and that's not 
quite following TDD since we should have a test that initially fails. Otherwise,
in a team environment there is a big chance that we will "forget" to implement the test. </p>

<p>A very useful trick when you are "scaffolding your tests" like I was is to remove the block, 
that is the do..end and RSpec will report the tests as pending. So my test now looks like:</p>

<pre class="brush: ruby;">
require File.dirname(__FILE__) + '/../spec_helper'

module TimeEntrySpecHelperMethods
  def create_time_entry(options = {})
    @user = User.new
    @project = Project.new
    TimeEntry.create({ :user => @user, :project => @project }.merge(options))
  end
end

describe TimeEntry do

  include TimeEntrySpecHelperMethods

  it "should be invalid without an associated User" do
    time_entry = create_time_entry(:user => nil)
    time_entry.should_not be_valid
    time_entry.errors.on(:user).should eql('must have an associated user')
    time_entry.user = @user
    time_entry.should be_valid
  end

  it "should be invalid without an associated Project" do
    time_entry = create_time_entry(:project => nil)
    time_entry.should_not be_valid
    time_entry.errors.on(:project).should eql('must have an associated project')
    time_entry.project = @project
    time_entry.should be_valid
  end

  it "should be invalid without an associated Project Activity"

  it "should know that it needs to be split across days" 

  it "should know how to split a time entry across multiple days" 

  it "should not have a value higher than 24 hours" 

end
</pre>

<p>Notice the do..ends are gone in the unimplemented tests. When we run the test we now get:</p>

<pre class="brush: shell;">
rake spec
(in /Users/bsbodden/Documents/projects/tempo)
...PPPP..

Finished in 0.074545 seconds

9 examples, 0 failures, 4 pending

Pending:
TimeEntry should know that it needs to be split across days (Not Yet Implemented) 
TimeEntry should not have a value higher than 24 hours (Not Yet Implemented)
TimeEntry should know how to split a time entry across multiple days (Not Yet Implemented) 
TimeEntry should be invalid without an associated Project Activity (Not Yet Implemented) 
</pre>

<p>Now that is cool! Thanks Joe.</p>

<p>Next we'll tackle a more challenging test and associated functionality: </p>

<h3>TimeEntry "should know that it needs to be split across days"</h3>

<p>This test should check that a TimeEntry can detect that it spans over multiple days. The test is simple,
set the start and end dates so that they span over multiple days and check that a method, let's call it 
"needs_splitting" returns true.</p>

<pre class="brush: ruby;">
  it "should know that it needs to be split across days" do
    time_entry = create_time_entry
    time_entry.start = 2.hours.ago(Time.today.beginning_of_day)
    time_entry.end = 5.hours.since(time_entry.start)
    time_entry.needs_splitting.should be_true
  end 
</pre>

<p>Run the test and watch it fail:</p>

<pre class="brush: shell;">
rake spec
(in /Users/bsbodden/Documents/projects/tempo)
...PFP..

1)
NoMethodError in 'TimeEntry should know that it needs to be split across days'
undefined method `needs_splitting' for #<TimeEntry:0x3467dc0>
./spec/models/time_entry_spec.rb:40:

Finished in 0.088024 seconds

8 examples, 1 failure, 3 pending
</pre>      </div>
    </summary>
  </entry>
  <entry>
    <id>tag:www.integrallis.com:Article16</id>
    <published>2007-10-22T09:44:53-04:00</published>
    <updated>2009-09-08T19:13:14-04:00</updated>
    <link type="text/html" rel="alternate" href="http://www.integrallis.com/blog/2007/10/24/building-tempo-with-rails-part-ii"/>
    <author>
      <name>Brian Sam-Bodden</name>
    </author>
    <title type="html">Building Tempo with Rails, Part II</title>
    <category scheme="http://www.integrallis.com/blog/category/ruby" term="ruby" label="Ruby"/>
    <category scheme="http://www.integrallis.com/blog/category/rails" term="rails" label="Rails"/>
    <category scheme="http://www.integrallis.com/blog/tag/rails" term="Rails"/>
    <category scheme="http://www.integrallis.com/blog/tag/ruby" term="Ruby"/>
    <category scheme="http://www.integrallis.com/blog/tag/agile" term="agile"/>
    <summary type="xhtml">
      <div xmlns="http://www.w3.org/1999/xhtml">
<p><img src="/ourblogs/files/rails.png" alt="Rails"/></p>

<p>Welcome back to part II of this series. Like I mentioned at the end of the first post; now we start the real work.</p>

<h2>BDD, TDD and DDD</h2>

<p>The sentence below summarizes what our development strategy will be:</p>

<blockquote>
    <p>"We are going to flesh the domain (DDD) with behaviours using (BDD) that we will express as tests (TDD) before writing any code"</p>
</blockquote>

<p>We are going to be using <a href="http://rspec.rubyforge.org/">RSpec</a>, a Ruby XUnit framework that facilitates the writing of tests that test behavior rather than state, in the spirit of Behavior-Driven Development (BDD). With RSpec we will write the tests that will guide the development of our application. We will try to stick with Test-Driven Development (TDD) as closely as possible. RSpec can be thought of as a domain specific language for behavior testing via expectations.</p>

<p>If you have been using Test::Unit and you want to use RSpec you don't have to chose one over the other. Although if you have to make a choice, RSpec will give you more readable tests.</p>

<p>If you want to get some background on the ideas behind BDD take a peek at </p>

<ul>
<li><a href="http://behaviour-driven.org/">behaviour-driven.org</a></li>
<li><a href="http://en.wikipedia.org/wiki/Behaviour-driven_development">Wikipedia: BDD</a></li>
<li><a href="http://en.wikipedia.org/wiki/Test_Driven_Development">Wikipedia: TDD</a></li>
</ul>

<h3>Installing RSpec</h3>

<p>As we did with Restful Authentication plugin we'll use Piston to install RSpec:</p>

<pre class="brush:shell;">
piston import svn://rubyforge.org/var/svn/rspec/tags/CURRENT/rspec 
   vendor/plugins/rspec
Exported r2563 from 'svn://rubyforge.org/var/svn/rspec/tags/CURRENT/rspec' 
to 'vendor/plugins/rspec'
</pre>

<h3>Installing RSpec On Rails</h3>

<p>An RSpec plugin that integrates with Rails exist which gives you the ability to create specs (read behavior tests) for your models, views, controllers and helpers. 
To install the <a href="http://rspec.rubyforge.org/documentation/rails/index.html">RSpec On Rails</a> plugin we again use Piston:</p>

<pre class="brush:shell;">
piston import svn://rubyforge.org/var/svn/rspec/tags/CURRENT/rspec_on_rails 
   vendor/plugins/rspec_on_rails
Exported r2563 from 'svn://rubyforge.org/var/svn/rspec/tags/CURRENT/rspec_on_rails' 
to 'vendor/plugins/rspec_on_rails'
</pre>

<p>To create the necessary RSpec directories and bootstrap code you need to run the rspec rake task:</p>

<pre class="brush:shell;">
script/generate rspec
      exists  spec
      create  spec/spec_helper.rb
      create  spec/spec.opts
      create  previous_failures.txt
      create  script/spec_server
      create  script/spec 
</pre>

<h2>Building Tempo's Domain</h2>

<p>Now we are ready to tackle the domain of the application</p>

<h3>Initial Domain Model</h3>

<p>I know it is a cliché but I actually modelled the domain on a paper towel which I later scanned (Jim Weirich is much more classy and uses fine napkins). 
Below is my first pass at the nouns that immediately came to mind when thinking about tracking time in the context of a project at a consulting firm:</p>

<p><img src="/ourblogs/files/tempo_nouns_take_1.png" alt="Tempo Domain Model"/></p>

<p>Based on the noun list above I created a simple UML-like diagram (in later issues of this blog I'll create something nicer):</p>

<p><img src="/ourblogs/files/tempo_domain_take_1.png" alt="Tempo Domain Model"/></p>

<p>The list below spells out what my thinking was when creating this model:</p>

<ol>
<li>A User is associated with a Person *</li>
<li>A User can be part of zero or more Projects</li>
<li>A Project belongs to a Client *</li>
<li>A Project has some Project Activities associated which are a subset of a global list of Activities</li>
<li>A TimeEntry represents time entered against a project by a User in the context of a particular Activity</li>
</ol>

<p>(1*) my thinking here is that I would have non-user entities in the system therefore I wanted to separate the Person/People
(3*) don't know yet if a Client is a Person, User or other Entity</p>      </div>
    </summary>
  </entry>
  <entry>
    <id>tag:www.integrallis.com:Article15</id>
    <published>2007-10-20T15:11:53-04:00</published>
    <updated>2010-05-01T17:22:57-04:00</updated>
    <link type="text/html" rel="alternate" href="http://www.integrallis.com/blog/2007/10/20/building-tempo-with-rails"/>
    <author>
      <name>Brian Sam-Bodden</name>
    </author>
    <title type="html">Building Tempo with Rails, Part I</title>
    <category scheme="http://www.integrallis.com/blog/category/ruby" term="ruby" label="Ruby"/>
    <category scheme="http://www.integrallis.com/blog/category/rails" term="rails" label="Rails"/>
    <category scheme="http://www.integrallis.com/blog/tag/rails" term="Rails"/>
    <category scheme="http://www.integrallis.com/blog/tag/ruby" term="Ruby"/>
    <category scheme="http://www.integrallis.com/blog/tag/agile" term="agile"/>
    <summary type="xhtml">
      <div xmlns="http://www.w3.org/1999/xhtml">
<p><img src="/blog/files/rails.png" alt="Rails"/></p>

<p>This is the first blog entry in a series about the process of going from idea to running software, while following all of the practices that we praise and push at our clients. </p>

<h2>Tempo</h2>

<p>At Integrallis we have been using an open source PHP-based Time Tracking Tool for a few years now. Don't get me wrong, we are thankful that this tool was out there to help us run our business but it's missing several features that we consider key, we don't have anybody on staff that knows PHP and the app is just plain ugly ;-)
So we decided to write our own, Yeah, yeah we are suffering from the not invented here syndrome but in my defense I thought it would make for a nice series of blog entries/tutorials on how we are approaching the building of this application using Ruby on Rails.
So let's start by describing in just a few paragraphs what is that we are looking to build.</p>

<blockquote>
    <p>"Tempo is a project based time tracking web application targeted primarily at small consulting firms and independent consultants"</p>
</blockquote>

<p>To track the development of Tempo we are using the agile project management tool <a href="http://www.caimito.net/">Savila</a> created by our friends at Caimito Technologies. We are starting with a few simple user stories that should take us to the basic functionality required.</p>

<p>The initial user stories revolve around the basics of a time tracking system, basic project/tasks management and the authentication system.</p>

<h2>Getting Started</h2>

<p>Before we get to the user stories let's make sure that you have everything that you need to get started. We are using Rails version 1.2.3, Ruby 1.8.6 and MySQL 5.0.24.</p>

<p>There are countless Rails tutorials on the web. If you've never worked with Rails I suggest you go through one the <a href="http://www.digitalmediaminute.com/article/1816/top-ruby-on-rails-tutorials">top RoR tutorials</a></p>

<p>I have created a skeleton rails application (hopefully you know how to do that by know but just in case you don't, simply type: </p>

<pre class="brush: shell;">rails tempo</pre>

We can use the about script to see what we have so far...

<pre class="brush: shell;">script/about


About your application's environment
Ruby version                 1.8.6 (i686-darwin8.9.1)
RubyGems version             0.9.2
Rails version                1.2.3
Active Record version        1.15.3
Action Pack version          1.13.3
Action Web Service version   1.2.3
Action Mailer version        1.3.3
Active Support version       1.4.2
Application root             /Users/bsbodden/Documents/projects/tempo
Environment                  development
Database adapter             mysql
Database schema version      4
</pre>

<p>At this point you should be able to get your skeleton application running.</p>

<h2>Initial User Stories</h2>

<p>The table and the Savila screenshot below show the user stories that we will be tackling on "Sprint #1" of the Tempo development. The duration of the Spring should be around 2 weeks (I'm building Tempo on my spare time ;-)</p>

<table border="1">
<tr><td>Story Id</td><td>Short Description</td><td>Status</td><td>Complexity</td><td>Business Value</td></tr>
<tr><td>TMPO-4</td><td>Login into the site</td><td>OPEN</td><td>10 points</td><td>Business Critical</td></tr>
<tr><td>TMPO-15</td><td>Site Admin adds global Activities</td><td>OPEN</td><td>20 points</td><td>Business Critical</td></tr>
<tr><td>TMPO-19</td><td>Site Administrator Creates a Project Owner Account</td><td>OPEN</td><td>20 points</td><td>Business Critical</td></tr>
<tr><td>TMPO-21</td><td>Site Administrator creates a User Account</td><td>OPEN</td><td>20 points</td><td>Business Critical</td></tr>
<tr><td>TMPO-25</td><td>Site Admin creates a Project</td><td>OPEN</td><td>20 points</td><td>Business Critical</td></tr>
<tr><td>TMPO-27</td><td>Site Administrator assigns a User as Project Owner for a given Project</td><td>OPEN</td><td>20 points</td><td>Business Critical</td></tr>
<tr><td>TMPO-29</td><td>User enters Time</td><td>OPEN</td><td>40 points</td><td>Business Critical</td></tr>
</table>

<p><img src="/blog/files/sprint-1-planning.png" alt="savila screenshot - sprint 1 stories"/></p>

<h2>Managing Plug-ins with Piston</h2>

<p>Before we start downloading and installing plugins I decided that I needed a better way to manage the plugins in my application. To accomplish this I installed <a href="http://piston.rubyforge.org">Piston</a>. Piston enables you to better manage the vendor branch. It does a better and simpler job that using svn:externals, and you can "install" plugins into your vendor/plugins directory and lock them to a certain version.</p>

<h3>Install Piston</h3>

<p>Install the piston gem by using the following command:</p>

<pre class="brush: shell;">
gem install -y piston

Bulk updating Gem source index for: http://gems.rubyforge.org
Successfully installed piston-1.3.3
</pre>

<h2>Restful Authentication</h2>

<p>Since a lot of the initial stories revolve around a User, a good starting point is to get an authentication system going. Since I want to also make Tempo a Restful Rails application. I will based my authentication system on the Restful Authentication plugin, which is a restful version of the familiar <a href="http://technoweenie.stikipad.com/plugins/show/Acts+as+Authenticated">acts<em>as_authenticated</a>. Let's use Piston to import the restful</em>authentication plugin and create our user model and sessions controller. I find that very often in web-based application the User model is a good starting point from where to flesh out the rest of the system.</p>

<h3>Install Restful Authentication Plugin</h3>

<pre class="brush: shell;">
piston import http://svn.techno-weenie.net/projects/plugins/restful_authentication 
   vendor/plugins/restful_authentication

Exported r2983 from 'http://svn.techno-weenie.net/projects/plugins/restful_authentication' 
to 'vendor/plugins/restful_authentication'
</pre>

<h3>Generate User model and the Sessions controller</h3>

<pre class="brush: shell;">
script/generate authenticated user sessions

----------------------------------------------------------------------
Don't forget to:

  - add restful routes in config/routes.rb
    map.resources :users
    map.resource  :session

 Rails 1.2.3 may need a :controller option for the singular resource:
  - map.resource :session, :controller => 'sessions'


Try these for some familiar login URLs if you like:

  map.signup '/signup', :controller => 'users', :action => 'new'
  map.login  '/login', :controller => 'sessions', :action => 'new'
  map.logout '/logout', :controller => 'sessions', :action => 'destroy'

----------------------------------------------------------------------

      exists  app/models/
      exists  app/controllers/
      exists  app/controllers/
      exists  app/helpers/
      create  app/views/sessions
      exists  test/functional/
      exists  app/controllers/
      exists  app/helpers/
      create  app/views/users
      exists  test/functional/
      exists  test/unit/
      create  app/models/user.rb
      create  app/controllers/sessions_controller.rb
      create  app/controllers/users_controller.rb
      create  lib/authenticated_system.rb
      create  lib/authenticated_test_helper.rb
      create  test/functional/sessions_controller_test.rb
      create  test/functional/users_controller_test.rb
      create  app/helpers/sessions_helper.rb
      create  app/helpers/users_helper.rb
      create  test/unit/user_test.rb
      create  test/fixtures/users.yml
      create  app/views/sessions/new.rhtml
      create  app/views/users/new.rhtml
      create  db/migrate
      create  db/migrate/001_create_users.rb
/> 
</pre>

<p>As the plugin clearly suggests I added the following code to my routes.rb file in /config</p>

<pre class="brush: ruby;">
  # Restful Authentication routes
  map.resources :users
  map.resource  :session, :controller => 'sessions'

  # Map to familiar URLs
  map.signup '/signup', :controller => 'users', :action => 'new'
  map.login  '/login', :controller => 'sessions', :action => 'new'
  map.logout '/logout', :controller => 'sessions', :action => 'destroy'
</pre>

<p>Ok now we have basic authentication and some tests to prove that. We could go ahead and add out changes to the User model but first let's run the migration in development and make sure that all the tests that the plugin generator created pass.</p>

<p>If you haven't done it yet, go ahead and configure the database and create the mysql instance for tempo_development</p>

<h3>Running our first migration for Tempo</h3>

<pre class="brush: shell;">
rake db:migrate
(in /Users/bsbodden/Documents/projects/tempo)
== CreateUsers: migrating =====================================================
-- create_table("users", {:force=>true})
   -> 0.0591s
== CreateUsers: migrated (0.0593s) ============================================
</pre>

<h3>Running the existing tests</h3>

<pre class="brush: shell;">
rake
(in /Users/bsbodden/Documents/projects/tempo)

Started
..............
Finished in 0.219704 seconds.

14 tests, 26 assertions, 0 failures, 0 errors
</pre>

<p>Yay! You can test the app (assuming that you've started the server) by pointing your browser to http://localhost:port /signup /login /logout </p>

<p>Now the real work starts, in the next installment of this series we will tackle the development of the domain using DDD (Domain Driven Development) and TDD (Test Driven Development). </p>      </div>
    </summary>
  </entry>
</feed>
