Writing A Rails Application With TextMate For Mac users, TextMate is powerful tool for writing code. But having a great tool is pretty pointless unless you know how to use it. By spending a few hours learning about TextMate’s features you can almost half the time it takes you to write code. This tutorial will walk you through creating a simple Rails app using some of TextMate’s more advanced features. Before you start, I’d recommend you get the latest version of the Ruby on Rails TextMate bundle and install it. Also – I realise the application from this tutorial is far from perfect but I figured this would be a good way to introduce the features and show examples of how they can be used. If you have any suggestions please leave a comment below. Lets create a new rails app, in your terminal type the following: rails new text_mate_demo Once the app has been created: cd text_mate_demo && mate . to open the full application in TextMate. In true Rails fashion, this demo is going to create a simple blog site. To create our first model type the following in your terminal window: rails g model Post title:string body:text rails g model Comment name:string body:text post:references Next, open comment.rb and press ctrl + | (or ctrl + shift + \) and 2 to run the migration. Next, still in TextMate, type ctrl + alt + cmd + D to hide the project drawer – we won’t be using it in this tutorial. Instead we’ll navigate by pressing cmd + T and typing (part of) the name of the file you want to open. Lets go to post_test.rb and write some unit tests for our Post model. Type cmd + T followed by “poste” and hit enter. For our unit tests we’ll create a setup method. Here’s a good chance to introduce tab triggers. Type “def” followed by the tab key. This should create a new empty method with the name highlighted. Name this method “setup” and hit tab again to jump down a line. To setup our unit tests lets create a new Post instance and run validation checks on it. require 'test_helper' class PostTest < ActiveSupport::TestCase def setup @post = Post.new @post.valid? end end On a new line type “test” and hit tab to create a new test. Lets call it “should not be valid without title”. As a shortcut to writing “assert_equal”, you can write “ase” and hit tab, then tab for the expected value and tab again for the actual value. I’ve also added another two tests to meet our requirements: require 'test_helper' class PostTest < ActiveSupport::TestCase def setup @post = Post.new @post.valid? end test "should not be valid without title" do assert_equal @post.errors.on(:title), "can't be blank" end test "should not be valid without a body" do assert_equal @post.errors.on(:body), "can't be blank" end test "should have many comments" do @post = posts(:one) 2.times { @post.comments.create! :name => "John Smith", :body => "This is a comment" } end end Save this page and then press ctrl + \ followed by 7 to test units. The three tests should fail. Now press alt + cmd + down to jump to post.rb. Our unit tests specify that our posts should not be valid without a title or a body. To quickly add a “validates_presence_of” validation, type “vp” and then press tab. Now type “title” and then press tab and delete to clear the extra options (which we don’t require here). For our second validation we’re going to try something different. On a new line, type “va” and then press esc. The escape key can be used to auto-complete any method, constant or variable name that’s already present on that document. This is a great way to save time retyping long method/variable names. To add our has_many association, type “hm” and hit tab. Type “comment” and then tab, delete again. These validations could do with being DRYed up but we’ll leave that for now. In the meantime, press cmd + / to start a comment and leave yourself a TODO note “TODO – DRY this up”. class Post < ActiveRecord::Base # TODO: - DRY this up validates_presence_of :title validates_presence_of :body has_many :comments end Now we need to create a Comment model so our third test passes. rails g model Comment name:string body:text post:references rake db:migrate Quick note – jump to comments.yml and populate the “post” attribute like so: one: name: MyString email: MyString post: one body: MyText two: name: MyString email: MyString post: two body: MyText Now jump to comment_test.rb, again using cmd + T and add some tests like so: require 'test_helper' class CommentTest < ActiveSupport::TestCase def setup @comment = Comment.new @comment.valid? end test "should belong to post" do assert_equal( posts(:one), comments(:one).post ) end test "should not be valid without name" do assert_equal(@comment.errors.on(:name), "can't be blank") end test "should not be valid without body" do assert_equal(@comment.errors.on(:body), "can't be blank") end end Again, run the tests, see the failures and then write the model: class Comment < ActiveRecord::Base belongs_to :post validates_presence_of :name, :body end The tests should now pass. There’re a whole bunch of shortcuts for commonly used methods. Most of them are used by writing a few letters and then hitting tab. To browse through them go to Bundles > Ruby on Rails. This may be a good time to DRY up the Post model. Press ctrl + shift + T to have a look at the annotations you’ve left in your code. You should see 1 TODO in post.rb. Click on the link to jump to this comment and remove the duplication: class Post < ActiveRecord::Base validates_presence_of :title, :body has_many :comments end Now we need a controller for our posts. By pressing shift + alt + cmd + down you should see the goto menu. Press 1 for controller. Since there isn’t already a posts controller TextMate will ask if you’d like to create one. Click “create”. (From this point let’s just imagine we’ve written tests first). Now we need an index action to display our posts. Again, using our “def” then tab shortcut, create an index action and try to add some code here to find all of the posts and order them by “created_at DESC”. But crap! We’ve forgotten the different options available for the find method. Here comes the coolest trick TextMate has to offer… Highlight the find method and press ctrl + H. A window will pop up with either 2 or 3 options. If you only see 2, then select “Documentation for Selection” and select “ActiveRecord::Base::find”. If you do have the 3rd option “Documentation for Word” then select it. This gives you a chance to browse the Rails documentation for any method and see examples of how to use it. This is a really powerful tool! By pressing cmd + H you can see the documentation for practically any gem you’ve installed. It also works for other languages like HTML and CSS so it’s a great way to learn as you go. You quickly read up on find and see the options available. Now you can add the required code to the index action: class PostsController < ApplicationController def index @posts = Post.where(['created_at > ?', 3.months.ago]).order("created_at DESC").limit(5).eager_load(:comments) end end To collapse this method and neaten your controller, press alt + cmd + 2. You can collapse foldings at different levels by using alt + cmd + 1,2,3 etc. With the cursor still in the index action, press alt + cmd + down to create the view template for the index action. To create rhtml tags press ctrl + >. By pressing this again you can cycle through the various erb tags available. To create new html tags press ctrl + <. Using this method, add the post title to our new heading tags like so: <% @posts.each do |post| %> <h3><%= post.title %></h3> <%= post.body %> <% post.comments.each do |comment| %> <% div_for comment do %> <p><%= comment.name %></p> <p><%= comment.body %></p> <% end %> <% end %> This tutorial could go on for quite some time but those are the commands that I feel are the most useful. You may have already noticed too that TextMate already has its own Rails tutorial which covers loads of the snippets etc. You can access this tutorial by pressing cmd + H and selecting “View Demo Help”. If there’s anything you’d like to see here that I haven’t covered, feel free to leave a comment.