Some rather vague thoughts on models in Rails and ASP.NET MVC. Mostly out of interest in the different approaches rather than as a critique of either framework, because, well because that's a different blog post....Let's imagine, for this little ditty, that we are dealing with a blogging engine.
class Post < ActiveRecord::Base
end
It's nice and clean, nice and simple, but, looking at the model, you have no idea what's in there. Instead, if you're a new developer on the project, you can scan through the schema.rb or dive straight into the database to find out.
Contrast that with ASP.NET MVC which takes a more explicit approach:
namespace YetAnotherBlogEngine.Models
{
public class Post
{
public int Id (get; set;}
public string Title {get; set;}
public string Body {get; set;}
public int Category_Id {get; set;}
public datetime Date_Published {get; set;}
}
}
So a new developer bounced in to the project knows what properties this model has by looking at the model rather than a schema.
I wonder, to myself mainly, if the differences are a function of the duck typed vs strongly typed nature of ruby vs c#, and the fact that with ASP.NET MVC the toolest (Visual Studio with its autocomplete and continual compilation process) was there before the framework, whereas Rails was developed as a framework before the toolset (Texmate, Vim + plugins, Host of other 3rd Party dev environments and obviously Sublime Text).
Let's continue and add some sort of constraint - perhaps a blog post must have a title. That makes sense. I'm looking at the code first method in ASP.NET MVC because I think it provides a little more of a like-with-like comparison to Rails.
Rails takes the approach that model level validations are the way to go:
Model-level validations are the best way to ensure that only valid data is saved into your database. They are database agnostic, cannot be bypassed by end users, and are convenient to test and maintain
So, we can enhance our model like so:
class Post < ActiveRecord::Base
validates :title, :presence => true
end
This, by itself, will not persist your constraint to the database schema. You would need to do that in your migration in Rails.
The Active Record way claims that intelligence belongs in your models, not in the database. As such, features such as triggers or foreign key constraints, which push some of that intelligence back into the database, are not heavily used.
and
Although Active Record does not provide any tools for working directly with such features, the execute method can be used to execute arbitrary SQL.
ASP.NET MVC on the other hand, is pretty strongly tied to SQL Server, or at least, the implicit assumption is that you're going to be using SQL Server, so applying constraints to a model (called data annotations) and then running your update-database (roughly the equivalent of a Rails migration) will apply your constraint at the database level as well as the model level (now I haven't validated every data annotation, but I'm talking about things like foreign keys and non-null values, and obviously this won't work with custom annotations).
So, our ASP.NET MVC model would look something like this:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.ComponentModel.DataAnnotations;
namespace YetAnotherBlogEngine.Models
{
public class Post
{
public int Id (get; set;}
[Required]
public string Title {get; set;}
public string Body {get; set;}
public int Category_Id {get; set;}
public datetime Date_Published {get; set;}
}
}
I've added in the using statements, because you have to explicitly pop the DataAnnotations in there.
What I like about the Rails style, is looking at your model, you get a quick sense of what validations are going on because they are all collected at the top. With ASP.NET MVC, getting an overview of the constraints on a model takes a bit longer. Especially when your model grows in size, because you have to scan through all the properties to single out which ones have data annotations. Also, annotations in ASP.NET MVC are a bit of a mixed bag, because apart from constraints, you can also specify the front end display of a field. For example:
[Display(Name = "Post Title")]
public string Title {get; set;}
will cause your views to render "Post Title" as the label for the Title field by default. Anyway, lets not get into that too much because the data annotations are actually part of the entity framework rather than the mvc framework per se.
A true like for like comparison between ASP.NET MVC and Rails is not really possible. ASP.NET MVC, actually wants you to develop in a Model, View, View-Model, Controller paradigm. This extra layer in .NET makes more sense when you start to work with the strongly typed views and you realise that .NET doesn't actually want your views to use your models in anything but the most basic examples. Though often it feels like you are writing code for code's sake.
I'm not sure there is any punch line to this post other than maybe accepting that each framework has a philosophy and you should "render unto Caesar" in each framework and go with the overriding ideas, idioms and philosophies.