Archive

Archive for February, 2009

Dear advertisers

February 26, 2009 1 comment

if you want me to see your advertisements, stop making them in your face, attention grabbing distractions.

Nearly every day I visit a NZ news site called Stuff, it’s a good way to get a quick snapshot of the days headlines and give my brains some downtime from coding.  I used to use IE, it was there and I didn’t have to think about it, but then a couple of years ago Stuff started adding those annoying fly out ads that forced me to interact with them.  I resented having such an intrusive ad so I went looking and found Firefox and Adblock, I haven’t looked back… until recently.

With the advent of Google Chrome I found a nice clean browser that does what I need and does it pretty well, except it doesn’t block ads.  I went back to the Stuff site today – this time I was using Chrome, and I was assaulted by annoying in your face adds that distracted me from my true purpose once again.  I wouldn’t mind the ads, except the incessant moving / blinking / changing keeps dragging my focus away from what I was reading ( most ads seem to act like that fluorescent light fitting in your office with the broken starter ).

I’m now back using Firefox to peruse the Stuff site and none of their advertisers get me eyeballing their ads, the only downside for me is I don’t get to choose the browser I use.

End rant.

PS If you’re still using IE in any shape or form – go grab Firefox (and maybe even Chrome).  Microsoft dropped the ball with IE long ago and still haven’t figured how to pick it up again.

Categories: General

SubmittedWith Parameter Binder – Which button was clicked?

February 23, 2009 2 comments

What do you do when you want to have more than one button submit a form and vary the actions taken depending on the button press?

Previously I would have done something like:


bool resetFilter = QueryContainsKey( "ShowAll" );

where QueryContainsKey is a simple method that scans the query collection looking for the “ShowAll” key (when an html form is submitted, the name of the button is passed in the request, in the same way that other form elements are – just without a value).

This approach works reasonably well – except it’s kind of ugly, repetative (I need to apply the same logic in at least 3 controller methods) and makes testing painful as I have to remember to add a value to the Query collection.

Then I discovered the IParameterBinder interface (have a look at the DataBindAttribute code and Ken Egozi’s excellent tutorial) and built the following:

    [AttributeUsage(AttributeTargets.Parameter, AllowMultiple = false, Inherited = false)]
    public class SubmittedWithAttribute : Attribute, IParameterBinder
    {
        private readonly string _buttonName;

        public SubmittedWithAttribute(string buttonName)
        {
            _buttonName = buttonName;
        }

        public int CalculateParamPoints(IEngineContext context, IController controller, IControllerContext controllerContext, ParameterInfo parameterInfo)
        {
            if( parameterInfo.ParameterType.Equals( typeof(bool) ))
            {
                return 10;
            }

            return 0;
        }

        public object Bind(IEngineContext context, IController controller, IControllerContext controllerContext, ParameterInfo parameterInfo)
        {
            var collectionKeys = new List();

            if( context.Request.HttpMethod == "GET" )
            {
                collectionKeys.AddRange( context.Request.QueryString.AllKeys );
            }

            if( context.Request.HttpMethod == "POST" )
            {
                collectionKeys.AddRange(context.Request.Form.AllKeys);
            }

            // Keys must be compared using case insensitive comparer - html is not case sensitive and neither should this be
            collectionKeys.Sort(StringComparer.InvariantCultureIgnoreCase);
            return collectionKeys.BinarySearch( _buttonName, StringComparer.InvariantCultureIgnoreCase ) >= 0;
        }
    }
[/sourceode]

This allows you to define a controller method like:

[sourcecode language='csharp']
public void ViewResults(Guid questionnaireId, [DataBind("SurveyFilter")]SurveyFilterBuilder surveyFilterBuilder, [SubmittedWith( "ShowAll" )]bool resetFilter)
{
...
}

and test it just like any other method, but when the action is called from a form submit, resetFilter will indicate if the form was submitted using the ShowAll button.  The html form looks like:

$Form.FormTag("%{method='Get'}")
<fieldset>
...
<button type="submit" id="apply" title="Apply the filter to the report">Apply</button>
<button type="submit" id="showall" name="ShowAll" title="Show all results">Show all</button>
</fieldset>
$Form.EndFormTag()

Wicked!  Now I have collapsed a bunch of repeated logic into a simple attribute (that is tested) that has the added benefits of making my action method signatures more obvious and made my tests much cleaner.

Updated 24 Feb: Searching the key collection for the button name is now case-insensitive

Categories: MonoRail

Random Thought Experiment – Swapping Variables

February 3, 2009 1 comment

Recently I was reading a post about using a fizzbuzz test to find developers that grok coding.  Some of the comments also talked about using a simple swap test (i.e. swap the values of these two variables) and how this could be done without resorting to the use of a third variable.

While I can appreciate the”geek factor” or XORing variables together such that you can swap their values without requiring the use of a third, I would not want to use this approach anywhere except where memory was extremely limted, it is horribly unclear what is happening to someone that does not know about or understand the approach.  This set me to thinking, how could you swap to variables around in a reasonably clear manner without resorting to the use of a third.  The following is what I came up with.

using NUnit.Framework;
using NUnit.Framework.SyntaxHelpers;

namespace Swap
{
    public class Swap
    {
        public static void DoSwap(int a, int b, out int swappedA, out int swappedB)
        {
            swappedA = b;
            swappedB = a;
        }
    }

    [TestFixture]
    public class SwapTest
    {
        [Test]
        public void DoSwap_Should_Swap_A_And_B()
        {
            int a = 3;
            int b = 5;
            Swap.DoSwap( a, b, out a, out b );

            Assert.That( a, Is.EqualTo( 5 ) );
            Assert.That( b, Is.EqualTo( 3 ) );
        }
    }
}

Simple, effective, completely pointless and fun to solve.

Categories: c#, General

NHibernate many-to-many mappings and order-by

February 3, 2009 2 comments

Update: Frederico Tolomei has pointed out that this now works as you would expect if you place the order by on the many-to-many tag like this:

    <bag name="SelectedOptions" cascade="none" lazy="false">
      <key column="Answer" />
      <many-to-many column="AnswerOption" class="AnswerOption"  order-by="DisplayIndex asc"/>
    </bag>

Just found this and it took me a while to figure out so posting here to remind myself as well as help anyone else who stumbles over the issue.

When you configure collection mappings in NHibernate, you can add an order-by attribute and specify the field to order the collection by as well as whether to sort ascending or descending.

With one-to-many mappings, the field you specify is a member of the entity contained in the collection so the following would contain a collection of Question instances sorted by DisplayIndex.

<bag name="Questions" cascade="all" order-by="DisplayIndex asc" lazy="false" fetch ="subselect">
   <key column="QuestionnaireSection" />
      <one-to-many class="Question" />
    </bag>

However, if the mapping is a many-to-many, the order by clause is applied to the association table – the table in the middle of a many-to-many association mapped into a relational database. I cannot use the order-by attribute on the following collection mapping.

    <bag name="SelectedOptions" cascade="none" lazy="false">
      <key column="Answer" />
      <many-to-many column="AnswerOption" class="AnswerOption" />
    </bag>

The implementation of this may be erroneous (and could be argued as counter-intuitive), however as it stands the order-by clause of a collection mapped as a many-to-many is not overly useful as we cannot sort a collection of entities in the same manner as we can with a many-to-one mapping.

Categories: NHibernate
Follow

Get every new post delivered to your Inbox.