Over the last few months I’ve realised that the speed at which I develop new projects is a lot quicker than it used to be. So I thought I’d share some of the things I’ve learned and also some quite obvious things (to me at least).
Use a Base Application
I’m obviously going to be horrifically biased due to the fact that I helped to develop Bort, but I think that base apps are the way to roll. They save you about half a days worth of development and let you get straight into developing your application rather than fucking around doing the same monotonous stuff every time.
So here’s a run down of base apps floating around:
Bort by myself and the rest of the Fudge development team
I haven’t used any of these apart from Bort, so I can’t really give you any opinion but everything I’ve seen by Thoughtbot and James Golick have always been awesome. Just look through them and find which one suits your needs.
The default Rails scaffold generator is alright for prototyping an app but let’s face it, you wouldn’t use it for everything. So why don’t you made your own that you can use for everything. At the start of the last project we worked on, we spent 2-3 days working on a scaffold generator that would help to generate parts of the admin.
We made the generator generate all the search stuff, add sortable tables, generate basic specs and a whole bunch of other awesome stuff. Now we can get an awesome admin section set up for a model by running line from terminal.
This must have saved us at least a weeks worth of time. Time that we can now spend making sure that the rest of the site is as brilliant as possible. With the extra time, you take it easy, or you could add extra features, improve the UI, whatever. Keep it RESTful, kids.
Use a Form Builder
I hate forms. No secret there. But alas, nearly every application you’ll develop need to have forms. I wrote a custom form builder for the chaps at Fudge and it saves us a hell of a lot of time.
Now instead of writing something like the following:
Now imagine you’re got to write close to 50 forms for an application. Can you guess which ones saves you time? Which one is more enjoyable to use? You got it.
Now while I wouldn’t say our form builder is ready for the general coding public (it isn’t), there are still a few out there.
I have used Semantic Form Builder by RubyPond before and it also happens to be the one we based out form builder on.
Build a Populate Rake Task
We started using Populator/Faker a couple of months a go and this is probably one of our biggest time savers. It’s a pain in the ass adding test data into your applications.
Ryan Bates has made a great railscast on how to use Populator along with Faker to generate fake datausing a rake task so I’ll leave it to his awesome video to tell you all about it.
There are also a couple other options out there for generating fake data, the random-data gem and the Forgery plugin.
This should really go without saying, but I’ve seen a few people trying to write (poor) code for tasks that have already been solved, tested and improved on.
Gems and plugins are probably your biggest time saver. One of the things I love about the ruby community is that a lot of people give back to it.
If you have a problem, have a look on the awesome GitHub and see if there’s a plugin/gem floating around that looks like it could solve your problem. Try it out. If it works brilliant, if not see if you can fix it and improve the original code. Then if someone else has the same problem, they can use the plugin. If everyone helps out, we all have an easier job, we can do less work and enjoy life more.
Seriously, Just Buy a Fucking Mac
Just do it. Stop making excuses. I was a Windows user for about ten years but mainly because I didn’t know any better. I now work full time on a mac, both at home and at work, and there’s not a thing you could do to make me go back to Windows.
Windows simply won’t do a lot of things that you’ll want to do. Background jobs? Not a chance. Git? oh yeah, you can use msysgit but who the fuck wants to open up a separate program just to use git? Fuck off Windows. You’re slow and you suck.
Why get a mac? Rails runs faster. You can use the best text editor around, TextMate. You can install all those gems and plugins that all say: “This won’t work on Windows”.
Think getting a mac is too expensive? Get a low spec mac mini for $599. That’s what I started using and even though it’s low spec I never had a problem with it. You can use your USB keyboard, mouse and your monitor from your Windows machine. Still think it’s too much? Have a look on Amazon…
So do you, my lovely readers, have any more suggestions/tips to speed up your development?
Edit: The code has been updated due to the awesome information presented in the comments.
For a project we’ve been working recently, we had to create four (uurgh) models from one form. After a lot of digging around and some trial and error we came up with a method which works well for us. I thought I’d document it for others as I couldn’t find a lot about it when originally trying do it.
Background
Say we have 3 models that are all mutually exculise from each other but we need to make sure that all of the models are valid before we save them. The original pplan was to use something similiar to the following:
The problem with this method is: if @person and @dog are valid and save correctly but @dog fails due to validation, then you end up with a person and cat in your database when you don’t want them. This leads to infinite amounts of problems, as rSpec has happily announced on more than one occassion.
The second thing I tried was checking that all the models are valid first then saving them:
While this looks good on the controller side, it actually sucks. If person is invalid then the errors are shown on the page as expected, but you don’t to see if any of the other models have any errors because valid? doesn’t get called on them. Aaargh!
The Solution
The View
Did you know you could pass in more than one model to error_messages_for? No, neither did I? What about fields_for? It’s a life saver. Let’s look at an example form for a Person, Cat and a Dog:
The main things to look out for here are error_messages_for and fields_for. We pass in an array of the objects we want to display errors for into error_messages_for using :object. This will display all the errors for those models, in our case the person cat and dog errors. Although you need to make sure all the errors for these models are being raised. We’ll look at this later on.
The other thing to take a look at is fields_for. I’ll let the API docs explain this for you:
Creates a scope around a specific model object like form_for, but doesnët create the form tags themselves. This makes fields_for suitable for specifying additional model objects in the same form.
So that’s our views done. On to the controller:
The Controller
This is the way we’ve been coping with the problem of validating all the models. I’m sure other people will have other suggestions, but this is what we’re rocking:
defnew@person=Person.new@cat=Cat.new@dog=Dog.newenddefcreate@person=Person.new(params[:person])@cat=Cat.new(params[:cat])@dog=Dog.new(params[:dog])# Run valid? on each model and check for failuresif[@person,@cat,@dog].all?(&:valid?)Person.transactiondo@person.save!@cat.save!@dog.save!endelse // Epic fail endend
The only line that you really need to checkout here is the line that runs valid? on each model and check results:
if[@person,@cat,@dog].all?(&:valid?)
This line runs through each model and runs the valid? method and checks that all the results are true.
As pointed out in the comments, this line could be replaced with:
if@person.valid?&@cat.valid?&@dog.valid?
The Person.transaction block makes sure that if one of the models fails to save then the other models aren’t saved as well. This stops you ending up with random saved models that shouldn’t be there.
I just thought I’d post about a few things that you should be doing with your forms and also a few things I just like to do.
Use Labels
I still don’t understand why there are a load of people who don’t use labels within their forms. They’re more semantic that using strong tags like alot of people seem to do. They’re also more user friendly. Also they’re useful for styling your forms.
The LABEL element may be used to attach information to controls. Each LABEL element is associated with exactly one form control.
If you have a submit button and a reset button, or anything similar, make sure people can tell the difference. I don’t want to fill in your huge form and then find I’ve accidentally clicked the reset button instead of the submit button.
An example is shown below:
Submit buttons on the left and sub actions on the right, see:
Always put the Submit Form button on the left and on the Clear Form button on the right. Never, ever put the Submit Form button on the right and the Clear form button on the left.
See?
I’ll post more when as they come to me, in my bizarre usability dreams. Feel free to post your own tips. Or to tell me that I know nothing at all about anything.