Sunday, February 26, 2012

Is the simple stuff usually simple?

I got stuck on this earlier this morning.  I needed to take a break and come back to it later.  I did work it out, and it turned out to be really, really simple.  But it had me confused for a while.

The code below is c#.  I'm building a new website, using MVC3, entity framework 4.1 and code first.  I've renamed the classes for this example.

I've got a class, lets called it 'Whatever', within it, I've got a field of type 'Something', like so...

    public class Whatever
    {
        [ScaffoldColumn(false)]
        public int WhateverId { get; set; }
       
        [DisplayName("Whatever Name")]
        [Required(ErrorMessage = "A Whatever Name is required")]
        [StringLength(255)]
        public string Name { get; set; }

        [DisplayName("Something Else")]
        [Required(ErrorMessage = "You've forgotten something else?")]
        public SomethingElse OtherDetail { get; set; }

        public bool Deleted { get; set; }
    }

My SomethingElse class is a simple one too...

    public class SomethingElse
    {
        [ScaffoldColumn(false)]
        public int SomethingElseId { get; set; }

        [Required(ErrorMessage = "A Something Else Name is required")]
        [StringLength(16)]
        public string Name { get; set; }
    }

Using Code First with Entity Framework 4.1, I can populate my DB...

      SomethingElse somethingElse = SomethingElseDal.GetDefaultSomethingElse(context);
 
      Whatever whatever1 = new Whatever
      {
          Name = "blah blah 1",
          OtherDetail = somethingElse
      };

      Whatever whatever2 = new Whatever
      {
          Name = "blah blah 2",
          OtherDetail = somethingElse
      };

      using(WhateverDal whateverDal = new WhateverDal(context))
      {
          whateverDal.Add(whatever1);
          whateverDal.Add(whatever2);
      };

This drops it all nicely into my database.  I have three fields in my 'Whatever' table:
  • WhateverId
  • Name
  • OtherDetail_SomethingElseId
My problem comes when I try and read a 'Whatever' record from my DB.  Something like this...?

      AppDBContext db = new AppDBContext();

      Whatever default = (from w in db.Whatevers
                         select w).FirstOrDefault();

This extracts a Whatever record, but my OtherDetail property is null.  I could do a 2nd query to populate it, but that'd be piss poor.   So, whats the best way to populate the field as part of the same query?

A dumbass question, but it's something I haven't faced until now.

My first instinct was to code it up like this...

       Whatever default = db.Whatevers
           .Include("OtherDetails")
           .FirstOrDefault();

But it didn't work, it was complaining about 'OtherDetails' not existing.

I've used this before, but only when adding in rows from other tables, when there's no foreign key in the primary table.

ie.

Lets say my structure was like...

    public class Whatever
    {
        [ScaffoldColumn(false)]
        public int WhateverId { get; set; }
       
        [DisplayName("Whatever Name")]
        [Required(ErrorMessage = "A Whatever Name is required")]
        [StringLength(255)]
        public string Name { get; set; }

        public IList<SomethingElse> OtherDetails { get; set; }

        public bool Deleted { get; set; }
    }

And my SomethingElse looks like...

    public class SomethingElse
    {
        [ScaffoldColumn(false)]
        public int SomethingElseId { get; set; }

        public int WhatverId { get; set; }

        [Required(ErrorMessage = "A Something Else Name is required")]
        [StringLength(16)]
        public string Name { get; set; }
    }

Then I could do something like this...

        internal Whatever GetPopulatedWhatever(int id)
        {
            Whatever whatever = this._context.Whatevers
                .Include("OtherDetails")
                .Single(w => w.WhateverId == id);

            return whatever;
        }


Then it hit me!  I'd had the right idea - especially after querying my mate Gary, and he suggested a similar thing.  I had a typo in my code!

        internal Whatever GetPopulatedWhatever(int id)
        {
            Whatever whatever = this._context.Whatevers
                .Include("OtherDetail")
                .Single(w => w.WhateverId == id);

            return whatever;
        }



I had an extra 's' on the end of 'OtherDetail'.  Easy!

Off the back of this, there's probably an extra bit that needs sharing...

Let's say my 'Whatever' belongs as a list of whatever's to a parent class.

    public class Parent
    {
        [ScaffoldColumn(false)]
        public int ParentId { get; set; }
       
        [DisplayName("Parent Name")]
        [Required(ErrorMessage = "A Parent Name is required")]
        [StringLength(255)]
        public string Name { get; set; }

        public IList<Whatever> Whatevers { get; set; }

        public bool Deleted { get; set; }
    }

    public class Whatever
    {
        [ScaffoldColumn(false)]
        public int WhateverId { get; set; }

        public int ParentId { get; set; }
       
        [DisplayName("Whatever Name")]
        [Required(ErrorMessage = "A Whatever Name is required")]
        [StringLength(255)]
        public string Name { get; set; }

        [DisplayName("Something Else")]
        [Required(ErrorMessage = "You've forgotten something else?")]
        public SomethingElse OtherDetail { get; set; }

        public bool Deleted { get; set; }
    }


I have a method that returns me my fully populated Parent class:

        internal Parent GetPopulatedParent(int id)
        {
            Parent parent = this._context.Parents
                .Include("Whatevers")
                .Single(p => p.ParentId == id);

            return parent;
        }


Even though this gives me my parent object, and a list of populated whatevers, what it hasn't done is populated the 'OtherDetail' field within each 'Whatever'.  To do that,  I need to make a slight amendment and add another Include:

        internal Parent GetPopulatedParent(int id)
        {
            Parent parent = this._context.Parents
                .Include("Whatevers")
                .Include("Whatevers.OtherDetail")
                .Single(p => p.ParentId == id);

            return parent;
        }


Nice!  :-)



Saturday, February 18, 2012

Yes, I use a Mac

Yep, I make a living out of writing software on the Microsoft platform, but at home I choose to have an iMac.

It does everything I want and it looks really smart on the desk.   The wireless keyboard and magic mouse.  I've even got a trackpad, and some of the hand gestures are a bit like a Jedi mind trick.

For my MS development I use VMWare Fusion, I have OSX on one screen and Windows 7 on another.  My Mac has 12gig of RAM, 4 of which is dedicated to Windows7.  Running both at the same time, side by side, and it's really slick.  Love it.

Some of the software that comes with the Mac is very easy to use and quite powerful.  Take iMovie for instance.   Last week, the wifey went out with her friend Charlotte, they took their horses across to Stainsby Grange and she took my camera along. 

I've got a Panasonic Lumix G3 camera.  It's like a mini-SLR.  It's really easy to use, takes nice photo's, but also full HD video.  Rachael spent half her time videoing the two horses while Charlotte charged around on the back of them.

One night last week, I'd been out to the pub, totally forgetting that I'd promised Charlotte the video edit of her with Elton.  So, I got the SD card out of the camera, stuck it in the iMac and I fired up iMovie.  I wanted to create something that was interesting to watch, but something that wouldn't take long to edit or upload.

iMovie comes with a bunch of predefined templates.  I decided I'd use the Adventure Movie Trailer template.  It ask you for the names of people in the trailer, and then gives you slots to drop your movie clips in to. Within 10 to 15 minutes, by trailer was done.

What do you think of the results?


Pay per click advertising, what's it all about?

I've been asked for a bit of advise on pay per click advertising.  I'm no expert in this field, but I know a little more than my friend does.   They've been offered pay per click advertising in a mobile phone app.  I need to ensure my friend understands what pay per click advertising is.

So, we're going to forget the smartphone argument for now.   Let's concentrate on online advertising and pay per click.

I'm an enthusiastic angler.  I love all types of fishing. I'll happily sit at the side of a pond, waiting for a carp to take my bait.  I'll stand in rivers trying for wild brown trout and grayling.  I'll go to a local trout lake and cast fly after fly, wandering around it, hoping for a bite.  I'm not very good at it, but I enjoy it, its a good break from the office and the pressure that comes with it.




So, back to pay per click...for the search term..

fishing county durham

...my friends site is currently 2nd in the list...

http://www.google.co.uk/search?q=fishing+county+durham&ie=utf-8&oe=utf-8&aq=t&rls=org.mozilla:en-US:official&client=firefox-a

But for the term...

fishing tackle county durham

...they're still on the first page, but bottom of the list.   When at the bottom of the page, there's a a massive risk that you'll slip to the 2nd page.  How many people look at the 2nd page?   Or even for the phrase...

fly fishing north east

http://www.google.co.uk/search?q=fly+fishing+north+east&ie=utf-8&oe=utf-8&aq=t&rls=org.mozilla:en-US:official&client=firefox-a

I can't find their site on the first few pages.  But, all the local anglers probably know where they are.  If they're to get more anglers visiting from the region, it might be an important phrase to target...?

You can spend ages optimising your site, trying to get to the top of the search engine rankings, or you can advertise online.  Or you can do both.  As well as the search results, you can pay to appear in search results.  As well as the 10 results, you'll also notice area's on the page where other sites are shown.  Like...



So, I've searched for 'fly fishing', there are three results at the top of the page with the coloured background.  There's also the ads down the right of the page.  All these results have appeared here because of pay per click advertising.

What does it mean?
Essentially, you pay for every time someone clicks on one of the links.  You don't pay to appear in the results, you only pay if someone clicks on that advert in the search result.

To appear in the results, you must bid against your competitors for a particular phrase.  Let's say you make a bid of 5p per click, and everyone has bid 50p, then they're going to appear in the advertising slots much more than you do.  But its only when someone clicks on that advert that the 50p is paid.  At 5p per click, you might appear in the advertising slot, but it'll be much less frequently than those that have bid the higher amount.

To ensure you don't spend too much on your advertising, you can set a budget.  It's a much more targeted form of advertising than advertising in a newspaper.

But it's not just search results where your ad will appear.  Take a look at this blog page.  I've made an agreement with Google that I'll show adverts on my blog page.   I don't choose the ads, Google manages those depending on the content of what I post.  As this blog is about fishing, I'm fairly sure there will be fishing related adverts appearing.  On other blog posts, there's no mention of fishing, its all software development, or Agile, so the adverts should be more targeted to the content.

Actually, thinking about it, that may not happen.  There could be other search terms that have made a higher bid.  The ads may also be targeted to specific visitors. Google know what you've searched for, they know the sites you visit.  They know a lot about you.  You can see what they think of you by visiting a page on their site.

Why would I want adverts appearing in my blog?
Every time someone clicks on a link, I take a cut of that pay per click.  It works for me, and it works for the people paying the pay per click.  They get their ads appearing in search results and also thousands of websites that have enabled Google AdSense.

So, for me allowing ads in my blog, I use Google AdSense, those wanting to advertise would use Google AdWords.

For iPhone smartphone users, Apple has come up with something similar, it's called iAd.  It allows people to place adverts within their smartphone applications. Moire details on the Apple website.

I don't know about Android, but as its from Google, maybe it uses AdSense.  I don't know, maybe someone can reply to this post...?


So, pay per click makes sense.  You get your website advertised all over the place, and you set your own budget.  If you're not getting the results, you can increase the click price.  You might be overwhelmed, so you might want to reduce it. But it's all manageable online.






Sunday, February 12, 2012

Were we being Agile without realising?

In an earlier post, I mentioned how in one job in London we had no form of project planning.  Thinking about it, I may have been a bit harsh.  In fact, I reckon we may have been extremely Agile, and not realised.  Well, how could we, I left that job in 2000, and the Agile manifesto wasn't written until a year later.

After posting that blog, I received a tweet from one of the guys I used to work, he joked, saying we were ahead of the curve. 
The Agile Manifesto
Individuals and interactions over processes and tools
Working software over comprehensive documentation
Customer collaboration over contract negotiation
Responding to change over following a plan
That is, while there is value in the items on the right, we value the items on the left more.
So, in that job we weren't planning everything in advance, we certainly weren't following any kind of waterfall methodology.  Thankfully.  I found something out this week.  Waterfall is accredited to Winston Royce.  He never used the term "Waterfall" and he actually described the process as a model that didn't work.  He actually said "… the implementation described above is risky and invites failure"

So why would anyone adopt a waterfall approach to developing their software?   I don't have the answer.  All I know is that the guy accredited for coming up with it, said it was risky and invites failure.   So, does that mean that any waterfall project is likely to fail?

Anyway, back to that job and why I now think it was really quite agile.

Look at the manifesto.  The first line, individuals and interactions.  Well, we certainly had that.  Over the road from the office was a pub, I could virtually see the bar from my desk. We weren't in there every day, but looking back, it seems like it.  We could go over at lunch time and not go back to work.  Nobody thought it a problem.  We'd have developers, various members of the business, from people in production, to the CEO.  We'd all chat, come up with idea's, update each other.  There was a real strong team spirit.

Nowadays, in DSDM, we have standup's, in Scrum, we have scrums.  In those days we discussed the same things, but simply did it in the pub.  The effect was still the same.
We didn't spend masses of time writing documentation.   That didn't mean we didn't do it, but there was only half a dozen devs.  The business need was for us to deliver the software, and then move on to the next urgent requirement. 

Customer collaboration?  We'd come up with an idea, go away see if it was feasible.  Early on we wouldn't know exactly how long it would take, but we could give a rough estimate.  We'd come up with a prototype, continually involving members of the business.  Showing them where we were at, inviting suggestions, responding to change.

We were working iteratively, constantly changing path from the feedback we were receiving.  Did the changes bother us?   Certainly not.   We were giving our guys the software they actually wanted.   They were constantly involved, they understood what was going on.  They knew that if they wanted to introduce a big change, then something would have to get dropped, or we'd change the delivery date.  But that was their choice, they were fully in control of the software they received.

If there was something we could give them early on, we'd get it in and deliver it.  It was worth our while, we all knew that there would be a pint (or two) in for us. 

We rarely worked late, there was never any pressure.  I wouldn't say it was easy, but the delivery velocity was at a pretty constant pace, a pace the business was happy with. We were never at risk of burning ourselves out.  We were all friends, we trusted each other, we were all working for each other.


There are 12 principals of Agile development:
  • Customer satisfaction by rapid delivery of useful software
  • Welcome changing requirements, even late in development
  • Working software is delivered frequently (weeks rather than months)
  • Working software is the principal measure of progress
  • Sustainable development, able to maintain a constant pace
  • Close, daily co-operation between business people and developers
  • Face-to-face conversation is the best form of communication (co-location)
  • Projects are built around motivated individuals, who should be trusted
  • Continuous attention to technical excellence and good design
  • Simplicity
  • Self-organizing teams
  • Regular adaptation to changing circumstances

We were certainly fulfilling all these principals.  We were agile and it has taken me 12 years to realise it.




Wednesday, February 8, 2012

Agile Storyboards and TFS2011 Preview

In an earlier post I talked about agile, and how we can manage stories and tasks by using a storyboard.  If everyone is keeping the board up to date, you can glance at the board and see the state of the project.  You can see who's working on what, what's done, and whats left to do.

But what if the project is being managed across more than one site?  And isn't maintaining a board, and what's in TFS a complete pain in the arse?

This is where a new feature of TFS2011 comes in.  A virtual storyboard.  In the web version, under 'WORK', click on 'board', and you get a list of all the stories and tasks in your project:


I can drag and drop my story in to the Active column...


That's brilliant.  Previously, we had to go into TFS, go in to the task and manually edit the task.  Now I just have to drag and drop it.  Easy!  I can check it in TFS - it's definitely updated my task...


As you can see, it hasn't set my Story to 'Active', but it's fairly easy to click the Story title and update it manually in the browser:


Love it!




Tuesday, February 7, 2012

Why I prefer Agile, and how we get stories and tasks in to TFS

  • Agile vs Waterfall.
  • Writing stories vs being spec driven. 
  • Delivering on time, on budget vs moving deadlines and changing budget
I've worked in a number of environments. 

At one job in London, we had no project planning, it was pretty much a case of having a chat in the pub, coming up with some ideas, then giving a rough estimate on how long it would take, then coming back a few months later and asking if that's what they wanted.  It worked because we worked very closely with the business and had a good idea of what they wanted.

At Vignette, we had full on Waterfall drilled in to us.  Plan, plan, plan.  Spend yonks planning, get it all detailed, then spend a short time doing the implementation. The great thing with this is that developers can come and go, and as long as they following the spec, they can chop and change people.  The risk is reduced.  You can divide it all up and have people in different offices deliver different parts of the system independently.  Really?  

The danger with this is that technology and companies change so quickly that the requirements can change.  The director that signed the deal could have moved on, and then someone else comes in, has different ideas, wants to do some cost cutting, believes in different technology.  Whatever.  From signing the original deal, doing all the up front planning, and eventually delivering it, the needs will undoubtedly have changed.   How do companies deal with this?   They put in some form of change control management.  So if requirements change, they can renegotiate the deal.

This is the great thing with Agile. You don't plan everything up front to the Nth degree, you feel your way to the solution. You come up with high level stories.  You do some very high level estimating against story points.  From this high level estimate you can give your timescales. You break it up in to Iterations - where at the end of each iteration you promise a delivery.  Within each Iteration you have a series of timeboxes.  Each timebox is managed as a detailed project.  It's within the timebox that you break your story down into a number of small manageable tasks, and you give your high level estimate against the task.  You don't have to break a story in to tasks, but I find it helps me.

You need to ensure that your story is delivered within the timebox.  If you can't, your story is too big.  Likewise, your task should be do-able in a day.  If you can't, try to break it down.

Its pretty much common sense.  You concentrate on the things you need to do next.

So, if you're used to spec driven waterfall, how do you get your head around Agile.  Do you still have requirements?  Of course you do, these are your stories.  You write your stories like this...

As a <type of user> I want <some goal> so that <some reason>

This could be something like:

As a customer I want to purchase my car insurance online so that I can save time

Actually, as a story, that's way too big, we'd refer to that as an Epic.  We could break it down to smaller stories...

As a customer I want to supply my postcode so that your system can look up my address and I can save time

That's probably quite a reasonable story.  You could realistically implement your address look up within a 2 week timebox.

You'd then break your story down into a bunch of tasks that the individuals on the team need to do, and put an accurate estimate in against the task.
You put your stories on cards, put your tasks on cards and then have a board up on a wall with people names down the side and a few columns along the top:
  • Unassigned
  • In progress
  • Awaiting code review
  • Checked in, awaiting deploy
  • In test
  • Complete
Or a flavour of your own to suit your own team and project.   On the back of the task card you can write the tests required to satisfy the testing of the task.
How do we put these in to TFS?   It's really easy.   In your Team Explorer, right click on 'Work Items', select 'New Work Items' and then choose 'User Story'.  Add your Story...

Add New Story

Then associate your task, under the 'All Links' tab, click the new button, as shown:

Add New Task to Story

This'll pop up a new window, where you insert the Task name:

Insert the Task Title

As you can see, it's adding the task as a child of the story.  Once you've chosen the task name, it'll switch to the Task details...

Add Task details

I've got the name in there, and put the same in the details.  However, in the details, you should really put in the detail of whats actually required for the developer to complete the task.  Under 'Effort', this is where you need to enter the time estimate.   As a developer works through a task, they can update the tasks, and change the figures for the hours done (completed), and left to go (remaining).  This helps when calculating the burndown.

So, I've now entered a few tasks against the story:

Three Tasks added to Story

What you'll see above is that the Story is assigned to me, and has a state of New.  When I start a task, I should change the Task and Story state to 'Active'.   Then as I complete my task, I can set them to 'Complete'.  Once all my tasks are 'Complete', I can set my Story state to 'Complete'.

Monday, February 6, 2012

Finding your way around TFS with Visual Studio 2010

So, one of my best friends has been using TFS in his work place for 6 months now, and we've also been developing some software together.  We've been using Subversion (SVN), with Ankh SVN, integrated into Visual Studio.  When the opportunity came up to try TFS2011 (with tfspreview) I decided to migrate us over. We'd been running with it for a couple fo weeks, but it was obvious I needed to get my mate up to speed with TFS.  I've been using it for over 4 years and started with TFS2005.  I've been happily using TFS2010 for a while.  So I went through and scribbled down the basics of some of the common features of TFS and sent them over in an email.
Again, its a lot of info that is probably best shared.


First thing you need to know, TFS isn't just a source control repository, but that's all we've been using it as so far.  The example below is showing two separate MVC3 projects, but they're not the point of this post, so I won't talk about them here.

Solution Explorer:
Solution Explorer
You know what this is, its the Solution Explorer, the clue is in the name.   However, it's worth mentioning the little symbols next to each file:

- the padlock means the file is checked in to TFS.  Nobody else has it checked out.
- the little person icon means its in TFS, but someone else has the file checked out.

We can have different types of check out.  We can lock the file exclusively, which means nobody else can check it out.  Or, as we have it set up, we allow parallel checkouts.  When you come to check in, if you're the first, it's straight forward, its a check in.  If you're following a checkin, you'll have to merge the file.  It might do it automatically, or you might have to manually merge it, in the merge tool. 
Why does it sometimes make you merge it and why sometimes can it automatically do it itself?
Lets say I make a change at the bottom of the file and you make a change at the top.  It's easy for the system to merge this, it'll do it itself.  But, if the changes are on consecutive lines, or even on the same line, then it'll ask you to merge the conflict yourself. 

Some say it's good practice to 'get latest' before checking in.  I'm not so sure.  But if it ever asks you to merge a file, lets share desktop and resolve it between us.

How do I find out who's got a file checked out?
If someone has a file checked out, you'll see the little person icon next to the file.  I'll show you the source control explorer later.  All you need to do is navigate to the file in the Source Controller and it'll show you who has the file checked out.
How do I add a new file?
If it's a piece of code, go to the directory you want to add it to, right click...

Add a new file to TFS

...and add your chosen type.  I chose to add a class, and call it bollocks...

New File Added to TFS
A new + symbol, that means its just been added to the project, but not yet checked in to TFS.

But, I've got an image I want to add!!
That's fine, just add an existing item...

Add an existing file to TFS
And your new file is in the project:



Existing file added to TFS

Next up, Pending Changes:

Pending Changes
Anything that you've added, updated, deleted, moved, etc will end up in your pending changes window.  I've got mine to show up at the bottom of the screen:

Pending Changes
So, my project file (MvcExample.csproj) file has been ammended because I've added two new files.  Then you can see that it's showing my two newly added files.   newImage.png is also marked as locked - this is because you can't have a parallel checkout on an image - how on earth would you merge it?

I'm not going to check these in, I don't really want them in my solution.  Instead, I'm going to highlight all 4 files and undo...

Undo Pending Changes
Next up, Team Explorer:

Team Explorer
Team Explorer
If we had multiple projects, we'd see more than just 'EntraNet', but that's our project.  Within there we have three items.
  • Work Items
  • Builds
  • Source Control
Work Items
We have a number of types of Work Item, and you can add one by right clicking and selecting New Workitem...

New Workitem

What are they all for? 

Bug
Ok, register a bug if somethings broken.  If you're getting an error, or its just not working, raise a bug.
Bug
Its fairly self explanatory.  But please do fill out the Repro Steps as though I'm an idiot.  I, or anyone, should be able to read the steps and reproduce the bug.  If I can't reproduce it, its not an bug.

Code Reviews, request and response
We use these extensively at work, but lets skip these 2, we're not using them.  Essentially, we can put in some check in rules, so that we can't check in without the changeset being reviewed and approved.
Feedback - Request and Response
I've never used these before.  These are new to TFS 2011.  Do we want to make use of this?  More details here:  http://blogs.msdn.com/b/visualstudioalm/archive/2011/09/20/feedback-on-working-software.aspx I think it probably makes sense.  When I think something has got to a state where it's usable, I can initiate a feedback request - and we do it via TFS, rather than email - so its all recorded.

Issue
Another new workitem type.  If there's something missing, or you don't like the way something works, raise it as an issue.  All comments get recorded in TFS.



Issue

They look fairly straight forward.
Shared Steps.
I have no idea what these are, lets ignore these.
User Story
A Story is a high level requirement. Something like:

As an Administrator, I want to be able to administer countries, so that I can keep my country list up to date


Task
Tasks hang off stories.  These are the physical actions that people need to take to complete the story.

Builds
Lets forget builds for now.  That for when we want to define a build, that builds our project, via a series of scripts, on the server (or another configured build server)
Source Control
This opens the source control explorer.

Here we can explorer the source, directly within TFS. We can navigate our way to a solution, and open directly from TFS:

Open a solution from Source Control Explorer
Double click the '.sln' file and it'll open the entire solution (in this case with 2 projects); A solution consists of one or more projects. 

You can get the history of of any item in source control, by right clicking and 'View History'

View History in Source Control Explorer
So, here I'm wanting to view the history of the whole of the solution.  It shows me all changesets in the history of the solutiuon.  You can check the history at Solution, Project Directory or Fiile level.  The history looks like this:


It's not showing the individual changes to files, its showing you each Changeset.  A changeset is the set of files grouped at a single checkin.  If you check in a single file on its own, you create a changeset with a siingle file, if you check in 100 files together, you've created a changeset with 100 files.

You can see the contents of a Changeset...

View Changeset

And you can see the specific changes in the file by drilling down even further...
Compare with Previous Version

Then that shows how it was, and how it is now...



View Differences

Sunday, February 5, 2012

MVC Model design

So, I've been toying about with MVC, and have a parent model, that has a list of children associated with it. Originally, I had my list of child objects loading up in the model though a lazy load. Big mistake, realised this through my integration tests. Now in my model, I simply declare my list of child objects like this:


And I populate it in my controller. Something like this:



Where do I put my AddChild functionality?  In the model, like this...




Or do I shove it in the Controller?