Twitter Feed Popout byInfofru

OverrideThis.com

Adventures in .NET Software Craftsmanship!

Installing Rails 3.0.7 on Ubuntu 10.10 (Maverick)

Recently I started reading “Learning Rails by Example” by Michael Hartl, and when going through the first chapters I learned the hard way that setting up Ruby and Rails on Ubuntu is not trivial.  So I decided, that for my own sanity, I should document the steps to get the latest version of Rails an Ubuntu environment up and running (Ruby 1.9.2 and Rails 3.0.7 at the time of publishing this blog).  I opted for not using RVM (Ruby Version Manager), which is a decision I expect to regret at some point, but I wanted to keep the process simple and limit the number of tools for an environment that is mainly going to be used for learning purposes.

 

Step 1 – Install Required Software

sudo apt-get install libxslt-dev libxml2-dev ssh
sudo apt-get install curl git-core build-essential 
sudo apt-get install zlib1g-dev libssl-dev libreadline5-dev
sudo apt-get install sqlite3 libsqlite3-dev

Step 2 – Uninstall Ruby and Rails
sudo gem uninstall rails
sudo apt-get purge ruby rubygems

 

Step 3 – Install Ruby 1.9.1 Full

sudo apt-get install ruby1.9.1-full

 

Step 4 – Install Ruby 1.9.2

wget ftp://ftp.ruby-lang.org/pub/ruby/1.9/ruby-1.9.2-p180.tar.gz
tar -xvvf ruby-1.9.2-p180.tar.gz
cd ruby-1.9.2-p180
./configure && make && sudo make install

 

Step 5 – Install Rails

sudo gem update
sudo gem install rails --version 3.0.7
sudo gem install ruby-debug19 ruby-debug-base19 ruby-debug-base19x ruby-debug-ide19 ruby-debug-ide

 

Step 6 – Install SQLite3

sudo gem install sqlite3 sqlite3-ruby

 

References

http://www.web2linux.com/05/installing-rails-3-on-ubuntu-10-04-lucid-lynx/

http://www.rubyinside.com/how-to-install-ruby-1-9-2-and-rails-3-0-on-ubuntu-10-10-4148.html

http://babinho.net/2010/09/installing-rails-3-in-ubuntu-10-04/

http://openrails.blogspot.com/2011/04/install-rails-3-in-ubuntu.html

http://www.ruby-lang.org/en/downloads/

Learning Razor–Writing a Once Extension

So, I have been –officially- using Razor since the ASP.NET MVC 3.0 release and I am loving every minute of it, but from time to time I still find myself looking back at Spark features that I wish I had in Razor. One feature that had been staring at me in the face for a while was the use of the ONCE attribute in spark.  The ONCE attribute allows you to specify with a very elegant syntax that something should just be rendered once no matter how many times is specified. (See code snippet below, or whole documentation here at the Spark website).

 

<!--  add jquery if it hasn't been added yet -->
<script once="jquery-1.5.1" 
  type="text/javascript" 
  src="~/content/js/jquery-1.5.1.js"/>

 

There are probably a couple of ways you could make this work in Razor but the easiest way to go about it is to write a Templated Html Helper (More info on the topic by Phil Haack here, and Andrew Nurse here).  Building a Templated HTML Helper allow us to use a syntax almost as sweet as Spark’s (see snippet below).

 

<!--  add jquery if it hasn't been added yet -->
@Html.Once("jquery-1.5.1",
    @<script src='@Url.Content("~/Scripts/jquery-1.5.1.js")' type="text/javascript"></script>
)

 

While the source code is extremely simple it does rely on the use of the HttpContext to establish uniqueness, this implies that it will safely work across Partial and Child Action calls but will not work across AJAX requests.

 

using System;
using System.Web.Mvc;
using System.Web.WebPages;

public static class HtmlHelperExtensions
{
    private static string RAZOR_ONCE_EXTENSION_KEY_FORMAT 
        = "RAZOR_ONCE_EXTENSION_KEY_{0}";

    public static HelperResult Once(this HtmlHelper helper, 
        string onceKey, 
        Func<object, HelperResult> template)
    {
        var contextKey = string
            .Format(RAZOR_ONCE_EXTENSION_KEY_FORMAT, onceKey);
        return new HelperResult(writer =>
        {
            if (helper.ViewContext.HttpContext.Items[contextKey] == null)
                template(null).WriteTo(writer);
            helper.ViewContext.HttpContext.Items[contextKey] = "OUTPUT_RENDERED";
        });
    }
}

Learning Razor-Shared Content & Layout

As web developer’s in the .NET world we have been spoiled by the advantages of using centralized master pages for managing shared content and layout since the 2.0 version of the .NET Framework.  The ASP.NET MVC 1.0 Framework was no exception we were able to take advantage of our knowledge of ASP.NET master page’s to layout the content of our views.  Now, Razor is no exception either, we still will have the ability to centralize the way content is laid out in our application but some of the mechanics of how the process works have changed.  In fact, one could argue that the way layout is defined in Razor is more inline with the way the Spark view engine (http://www.sparkviewengine.com) does rendering than traditional master pages.

 

Layout Pages

In Razor the concept of a master page is equivalent to a layout page, and one could argue that a similar comparison could be made between the concept of ASP.NET placeholders and sections in Razor.  The following snippet shows what a very basic Razor layout page looks like.  As you can see this is mostly a plain vanilla HTML file the only exception is the directive @RenderBody() which is just a method call that tells Razor where to render the Contents of the child view.

 

<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="utf-8" />
        <title>My WebSite</title>
    </head>
    <body>
        @RenderBody()
    </body>
</html>

 

A basic child view would just specify its layout page and provide the content that is going to be rendered by the @RenderBody() method. As you can see in the following snippet the code for the template is very minimalistic and elegant.

 

@{
    Layout = "~/_SiteLayout.cshtml";
}

<h1>Hello World!</h1>
<h2>Hello World!</h2>
<h3>Hello World!</h3>

 

So far the two samples (snippets) have been very basic, so lets complicate things a bit what if we wanted to have a three column layout.  Well we would still want the main section of the page to drive of the @RenderContent() functionality but for the additional sections you can use Razor’s @RenderSection() method to define additional section’s that can be filled with content from our child views.  The following is the snippet for a three column layout page using CSS.

 

<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="utf-8" />
        <title>My WebSite</title>
        <style>
            #container { width: 700px; }
            #left { float: left; width: 150px; }
            #content { padding: 0 210px 0 160px; }
            #right { float: right; width: 200px; }
            .clear { clear: both; }
        </style>
    </head>
    <body>
        <div id="container">
            <div id="left">
                @RenderSection("left", required:false)
            </div>
            <div id="content">
                @RenderBody()
            </div>
            <div id="right">
                @RenderSection("right", required:false)
            </div>
            <div class="clear"></div>
        </div>
    </body>
</html>

 

The “required:false” parameter specifies if the child view is required to provide content for this section in our case the left and right sections will be optional.   The following is a sample snippet of a page that provides content for all sections, as you can see it is still very minimalistic and elegant.

 

@{
    Layout = "~/_3ColLayout.cshtml";
}

<h1>Main Content</h1>

@section left {
    <h1>Left Content</h1>
}

@section right {
    <h1>Right Content</h1>
}

 

Well, this sums up all the basic information you should need to get started with using layout pages in Razor.  Thanks for reading!

Learning Razor–Writing an Inline Recursive HTML Helper

I have been using Spark (http://www.sparkviewengine.com) as my default view engine for the past 5 or 6 months and I love everything about it.  I like its elegance, simplicity and I depend on some of its features to be efficient in doing most of my daily tasks.   That being said, there is a new kid on the block and his name is Razor.  Razor, will be an out of the box alternative for the ASP.NET WebForm’s view engine for ASP.NET MVC3 (Read Scott Guthrie’s blog on the topic here).   I don’t intend to write a full blown tutorial on Razor,  but as I learn the basics for this alternative view engine, I will try to write some “Learning Razor” posts that relate my experience in learning this new technology.

 

Writing an Inline Recursive Html Helper

The Spark view engine provides you with the ability to define inline macros that allow for recursive calls (Read Louis DeJardin blog on the topic here, and additional documentation here).  These macros are extremely useful for rendering a hierarchical structure such as the one in the following snippet.

 

<ul>
  <li>Fuller, Andrew
    <ul>
      <li>Davolio, Nancy</li>
      <li>Leverling, Janet</li>
      <li>Peacock, Margaret</li>
      <li>Buchanan, Steven
        <ul>
          <li>Suyama, Michael</li>
          <li>King, Robert</li>
          <li>Dodsworth, Anne</li>
        </ul>
      </li>
      <li>Callahan, Laura</li>
    </ul>
  </li>
</ul>

 

Now, the Razor view engine allows you to easily build a hierarchical structure by the use of inline HTML helpers that can be called recursively.  The following is a basic snippet of a “Hello World” inline HTML helper, and a call to trigger its functionality.

 

@HelloWorld("Roberto!")

@helper HelloWorld(string name) {
    <h1>Hello World! @name</h1>
}

 

Finally, if we wanted to output the html from the first snippet using Razor we could write the following inline HTML helper.

 

@model IEnumerable<OrganizationNodeViewModel>
@using MVC3.Playground.ViewModels;
@{
    View.Title = "OrganizationTree";
    Layout = "~/Views/Shared/_Layout.cshtml";
}

<h2>OrganizationTree</h2>

@OrgTree(Model, null);

@helper OrgTree(IEnumerable<OrganizationNodeViewModel> nodes, int? parentId) {
    if (nodes.Any(n => n.ParentId == parentId)) { 
    <ul>
        @foreach (var node in nodes.Where(n => n.ParentId == parentId)) {
            <li>
                @node.DisplayName
                @OrgTree(nodes, node.Id)
            </li>
        }
    </ul>
    }
}

MVC Model Validation–Refactor (Part Deux)

This post enhances the functionality of the code in the Blog titled “MVC2 Validation and Testing” at the following link. 
http://blog.overridethis.com/blog/post/2010/04/22/MVC2-Model-Validation-and-Testing-Scenarios.aspx

 

A comment was made on one of my previous blogs requesting additional functionality for the extension method I wrote in April for testing controller action’s that rely on MVC2 Model Validation.  The request was simple, to be able to test class level validation attributes such as the ones found on the ChangePasswordModel in the default MVC2 project template.   Well, as requested!

 

public static class ControllerExtensions {

    public static ActionResult CallWithModelValidation<TController, TResult, TModel>(
            this TController controller, 
            Func<TController, TResult> action, 
            TModel model)
        where TController : Controller
        where TResult : ActionResult
        where TModel : class {

        var provider = new DataAnnotationsModelValidatorProvider();

        var metadata = new List<ModelMetadata>();
        metadata.Add(GetMetadataForClass(model));
        metadata.AddRange(GetMetadataForProperties(model));

        foreach (ModelMetadata modelMetadata in metadata) {
            ApplyValidatorsFromMetadata(model, provider, modelMetadata, controller);
        }        
        
        return action(controller);
    }

    private static ModelMetadata GetMetadataForClass<TModel>(TModel model) 
        where TModel : class {

        return ModelMetadataProviders
            .Current
            .GetMetadataForType(() => model, typeof (TModel));
    }

    private static IEnumerable<ModelMetadata> GetMetadataForProperties<TModel>(TModel model)
       where TModel : class {
        return ModelMetadataProviders
            .Current
            .GetMetadataForProperties(model, typeof(TModel));
    }

    private static void ApplyValidatorsFromMetadata<TModel, TController>(TModel model, 
        DataAnnotationsModelValidatorProvider provider, 
        ModelMetadata modelMetadata, 
        TController controller)
            where TController : Controller
            where TModel : class {
        
        IEnumerable<ModelValidator> validators = provider
            .GetValidators(modelMetadata, new ControllerContext());
            
        foreach (ModelValidator validator in validators) {
            IEnumerable<ModelValidationResult> results = validator.Validate(model);
            foreach (ModelValidationResult result in results)
                controller.ModelState.AddModelError(
                    modelMetadata.PropertyName ?? "Model", 
                    result.Message);
        }
    }
}