- The Classic test is back! - Due to popular demand, we're bringing back the original fivesecondtest! Whilst everybody loves the click test, we've had a lot of people comment that for their particular needs the original test actually gave a better result. We listened, and so it is back!
- The Click test has been revamped - We found that clicking is great, and keywords are great...but clicking and then remembering WHAT you clicked is tough! In this update, we'll unhide the image for Click tests! This means that users can flag the most prominent areas without having to play the memory game to remember what the saw.
- Keyword report has been improved - A common request was to have manual sorting of keywords in addition to the auto-sort. In many cases users would refer to the same item by two common terms that weren't auto matched. E.g. "woman" and "girl" or "jersey" and "jumper". The updated keyword test will allow users to drag like-terms together and combine the results!
- Better instructions - Maybe it's because we keep changing stuff....or maybe it's just because we got it wrong.... but a lot of people asked for clearer instructions on HOW to participate in a five second test. We hear you! Instructions are now clearer (we hope!) and tests are easier to participate in!
- BUGS! - Yes we had bugs. We've been fixing them...we promise!
[Migration(1)]
public class _001_Init : Migration
{
public override void Up()
{
Database.AddTable("dbo.tbl_Tokens",
new Column("TokenId", DbType.Guid, ColumnProperty.PrimaryKey),
new Column("UserId", DbType.Guid, ColumnProperty.NotNull),
new Column("DatePurchased", DbType.DateTime),
new Column("DateUsed", DbType.DateTime)
);
}
}
Where I change my process is how I set up my projects and how I run my migration. This is for a web application obviously btw.
Do this much (taken from the getting started Wiki):
1. Add a new class library project. In this example it's called Called DBMigration.
2. Create a lib directory in your DBMigration project, and extract all the dotnetmigrator DLLs into it. You can exclude database-specific DLLs that you don't need. e.g. If you're not using Oracle, you don't need Oracle.DataAccess.dll.
3. In your DBMigration project, add a reference to the Migrator.Framework.dll. That's the only additional reference you need in the project.
Now....Ignore the rest of the steps, and do this instead :)
4. Create your first migration class (like the one above).
5. In your web application, add a reference to Migrator, Migrator.Framework and your DBMigration project.
Here's the trick for the lazy peeps that can't be bothered messing with MSBuild and build targets!
In your Global.asax file... you want something like this:
protected void Application_Start()
{
string strConnString = ConfigurationManager.ConnectionStrings["AspNetSqlProvider"].ConnectionString;
Assembly a = System.Reflection.Assembly.Load("DBMigration");
Migrator.Migrator m = new Migrator.Migrator("SqlServer", strConnString, a);
m.MigrateToLastVersion();
}
Whenever you update the code for your application, on first run the application will automagically update the database using your migration scripts! Nifty!
A few important things to take note of here!
The first thing to understand is the connection string. I set up my connection strings using an external XML which is referenced from web.config....like this
<connectionStrings configSource="connections.config"/>
And in my connections.config file I have the connection string for the Live OR test OR staging server. There is different version of this file on each respective server (thus make sure it's not in your solution if you use VS deployment!).
Why? So that when I deploy my application to the test server, or to staging, it will be updating the database for THAT server only. This means I have a seamless means of updating my database at the same time as updating my code. No batch files, no configuration, no build targets! Just run it, and it updates the right database!
Now, obviously this is NOT ideal for all situations. You'd really need to be sure that this approach is suitable for what you need. For us, we do infrequent updates to the live server, but are constantly updating our staging server. This approach means that whenever we deploy and run the website, we know the database is going to be update and correct!Then some JQuery....<form id="EmailForm" action="/test/email" method="post"> <input id="emailAddress" type="text" value="email address" /> <input type="submit" value="go" /> </form>
OK, so far so good. All pretty straight forward. That, of course, would work with any server side technology...not just .NET MVC. BUT, the reason I like this so much is because with MVC we don't even have to bother with a responding page. Previously in .NET you'd have to create an ASPX page or web service just to handle this AJAX request (or a library of them perhaps). If you have a route setup already, all we need is a method in our controller class to handle the AJAX request!$("#EmailForm").submit(function() { //capture the submit event of our form $.ajax({ //create an AJAX request type: "POST", //use POST (we could also load this from the form if wanted to) url: $("#EmailForm").attr("action"), //get the URL from the form data: $("#EmailForm").serialize(), // this one line turns our whole form into tasty AJAX snacks! success: function() { alert("win!!!1!1!") //we got a 200 back...it worked! }, error: function(XMLHttpRequest, textStatus, errorThrown) { alert("epic fail!") //something went HORRIBLY wrong! } }); return false; //don't forget to cancel the event so we don't submit the page! });
That's all there is to it! Of course, this particular method doesn't return anything to the AJAX callback (except an error if something breaks!)..... so you'd probably want to return something if the address is invalid and show a nice error to the user. But I'm keeping it simple here. The crux of what is cool about this, however, is the separation between HTML and code. Because MVC doesn't have tightly coupled Pages/Classes/Code behind, you can not only reduce the amount of code you write (by doing away with superfluous aspx pages and reusing existing functions), but you increase the number of ways you can use the code you have already written. Doing an AJAX request becomes nothing other than another type of View.... the Controller doesn't have to care where the request is coming from and it means neither do you![AcceptVerbs(HttpVerbs.Post)] public void Email(FormCollection form) { string emailAddress = form["emailAddress"]; // validate the email address ..... //create the email message MailMessage msgMail = new MailMessage("info@angrymonkeys.com.au", emailAddress); // do some email content stuff ....... // send the email! smtp.Send(msgMail); }
When I first saw that, I thought... yeah ok. That could work. I've seen plenty of similar methods as well, revolving around selecting a customer, user, book or whatever by id, return the customer, user or book and then adding it to the object we want to save... and then saving it. The problem here, as far as I can tell is that you end up making an unneccesary select from the database. If we already now the key for the Customer, then we SURELY can just insert that into the table along with the rest of the data?!? Am I right? Yes. I am. Next time you go to create an Order, have a look just under Customer in the intellisense drop down.... you'll see CustomerReference. If your data model is right, this should be an Entity Reference to your customer. This is the key to inserting your Customer ID (pun intended).Model.Order order = Model.Order.CreateOrder(); order.Customer = (from c in Customer where c.Id == custId select c).First(); db.SaveChanges();
That's it. That's all you need to do! The only trick to this is sometimes working out what the hell "Model.Customer" should be. The easiest way to find that is to type:Model.Order order = Model.Order.CreateOrder(); Model.CustomerReference.EntityKey = new EntityKey("Model.Customer", "Id", custId); db.SaveChanges();
...and let Intellisense come up and remind you what your entity sets are called. By default it can create Customer as CustomerSet or something equally strange (Of course, "db" is whatever your ObjectContext is called). Also make sure you get your casing correct, as customer != Customer :) Alandb.
The last few months have been a crazy time for Angry Monkeys, so much so that we’re seriously considering a name change to Crazy Monkeys. We've been so focused on doing paid work; we've completely forgotten to work on our own projects. We have a number of world-changing web solutions on the go, but just haven't had the time to get them over the line. Heck, we still haven't gotten around to building our own website! This is making our Angry Monkeys even angrier! So, what to do? Get more Monkeys of course!
We're looking for talented, enthusiastic, experienced developers with a keen sense of what makes the web tick. Being a small company (well, there is only me), the role involves a whole lot of responsibility, and a whole lot of opportunity. This is a chance to get on at the ground floor of company that is truly going places (we’re actually on the 13th floor for the superstitious). Most importantly, it is a chance to control the direction of your own future.
We won't be offering a whole heap of cash to the successful applicant, because if that is what drives you, then you don't have what we need. We need someone whose passion is developing cutting edge web applications and technical solutions to some pretty scary problems. We need someone with uber .NET experience, extreme JavaScript knowledge, top notch SQL Server design and development skills, and a heap of prior web development projects up their sleeve. PHP, Flash, Photoshop and Bow hunting skills are a bonus. We can offer ultra-flexible working hours, the opportunity to work from home or from the office when you choose, your own computer with big-ass LCDs and most of all; that warm fuzzy feeling you get from making a real difference.
All applicants will need to display a passion for web development, be able to demonstrate the ability to create cutting edge web applications, self-learn and most importantly, have a serious commitment to quality. We don’t create half-assed solution, and “hacks” are definitely out.
Please apply via e-mail to givemeajob@angrymonkeys.com.au including resume, examples of work and references.