Main Content:

Posts tagged as 'basics'

18 Git and GitHub 0 comments

June 21

After using SVN for a year or two, I was reluctant to make the switch to Git, and I know it can be a daunting idea for anyone who has not used a version management system before, with the forking, branching, merging, differences and the like, but it really isn't difficult, so I thought I'd give the lowdown on how to get yourself setup for mobile programming using Git and Github.

Installing Git

For a start you will need to download the Git source from git.or.cz, then simply Google for guides on installing it on your operating system be it Mac OS X, Linux or Windows.

I am no master of compiling using the command line, but most others will provide a step-by-step guide with the exact commands you need to run.

Using Git

This is where Git really comes into it's own. Rather than going into the complicated SVN procedure of creating a repository and checking in and out before you can do anything. Git repositories can be started in place with nothing more than:

git init

So if you're using Rails, simply change directory to your Rails app then run the above command.

You will then want to setup Git to ignore some files, so create a .gitignore file and open it up in your text editor:

touch .gitignore mate .gitignore

Now on each line you can add file strings to ignore, here is an example of my default Rails ignore file:

.DS_Store */.DS_Store log/*.log db/*.sqlite3 db/schema.rb tmp/*

Save the file, and we are ready to add our files to the repository using:

git add .

Then you can run your commit to send them to the repository:

git commit -a -m 'My first commit'

Now your files are in the repository but that isn't much use unless you send it to a remote server for backup, or downloading at multiple locations, so on to GitHub.

Working with GitHub

GitHub provides hosted repositories so your projects can be backed up and more importantly accessed by others in your development team. The service is free for open source projects, however if you want to have a private repository then you can for the mere cost of $7 a month, a price nobody can argue with.

There is all the usual integration, with Twitter, Lighthouse, Basecamp and more, so you can stay clued up on what is going on within your project without having to reload the website every 10 minutes.

Again, setting up the remote repository can be a scary task, but GitHub guides you through providing exactly what commands you need.

Once you have provided your SSH key (don't worry there is a guide for that too) and setup a repository on GitHub, you can link your local repo to it easily with:

git remote add origin git@github.com:GITHUB_USERNAME/GITHUB_REPO_NAME.git

Then a simple push command will upload all the latest commits to the service:

git push origin master

So now you are a fully fledged mobile / collaborative developer! How does it feel? Good right?

Re-downloading a Repository

This process is known as cloning, and is very simple. When you clone a repository, Git will download all the files you need into a new repository that goes by the same name as your remote one, so if on GitHub you have a project called "notes", Git will make a folder called notes automatically, so make sure the folder you are in when you make the clone, doesn't have a notes directory already.

git clone git@github.com:GITHUB_USERNAME/GITHUB_REPO_NAME.git

After running the command above, you can make your changes, commit some updates and then push back to GitHub.

So that's a basic introduction to using Git, you don't need to be confused with all the advanced features when you are just getting started so hopefully you found this helpful!

19 Rake db:backup 0 comments

July 22

I apologise for the quietness around ThinkRefresh recently, but I have been busy on a few projects, however some of them are coming to a close (or rather, an open...), so I have had little chance to post. Anyway, enough excuses, one of the good things to come from my work on these projects is the many things I have developed or discovered a long the way, many of which I hope to post here, so here is the first.

It is always a pain manually backing up your database, and even if your web host does backup for you, they may not keep copies long enough for your liking, so with a helping hand from S3 you can simply install the below rake task as a file in your lib/tasks directory and drop in your AWS keys. I cannot take full credit for the script, so I have quoted those involved within it, all I did was drop in SQLite support, so this was more of a discovery than a development.

One final note before you dig in, if you add support for another database engine or make any changes, please feel free to update the code on gist.github.com/739.

# S3 Backup Task for MySQL & SQLite # Assumes InnoDB tables # If using MySQL database user needs the "reload" permission on the database (for --flush-logs in mysqldump) # # Stores files in Amazon S3 using the excellent AWS Gem: http://amazon.rubyforge.org/ # For information about Amazon S3: http://aws.amazon.com/s3 # # Installation # 1) Install AWS Gem # 2) Enter your S3 Bucket, access_key_id and secret_access_key in this file # 3) Run (rake db:backup) # # Inspired by code from: # http://blog.craigambrose.com/articles/2007/03/01/a-rake-task-for-database-backups # http://www.rubyinside.com/advent2006/15-s3rake.html # http://info-architects.net/2007/08/25/rake-task-for-mysql-backup-to-amazon-s3/ # # Support for SQLite added by Ryan Townsend of http://thinkrefresh.com namespace :db do require "aws/s3" require "ftools" desc "Backup database to Amazon S3" task :backup => :environment do BUCKET = "my.bucket.example" begin AWS::S3::Base.establish_connection!( :access_key_id => "ABC", :secret_access_key => "XYZ" ) db_config = ActiveRecord::Base.configurations[RAILS_ENV] backup_path = "db/backup" File.makedirs(backup_path) case db_config['adapter'] when 'mysql' stored_file = backup_file(backup_path, "#{db_config['database']}.sql.gz") sh "mysqldump -u #{db_config['username']} -p #{db_config['password']} --single-transaction --flush-logs --add-drop-table --add-locks --create-options --disable-keys --extended-insert --quick #{db_config['database']} | gzip -c > #{stored_file}" when 'sqlite3' stored_file = backup_file(backup_path, File.basename(db_config['database'])) File.copy "#{RAILS_ROOT}/#{db_config['database']}", stored_file else puts "Unable to backup databases of type: #{db_config['adapter']}" end if stored_file && File.exists?(stored_file) puts "Created backup: #{stored_file}" puts "Storing file in S3: #{BUCKET}" AWS::S3::S3Object.store(stored_file, open(stored_file), BUCKET) puts "Backup Complete" else puts "Unable to create backup" end rescue AWS::S3::ResponseError => error puts error.response.code.to_s + ": " + error.message end end def backup_file(path, file) File.join(path, "db_#{Time.now.strftime("%Y%m%d%H%M%S")}_#{file}") end end

16 Rails 101: Generators 7 comments

June 08

So you're just about to crack on and dive into that code, but wait, you don't even need to do that! Rails comes with generators for basic functionality so you can get going as quickly as possible.

Because Rails follows the strict file structure we covered in the previous screencast, you can have a large amount of files automatically generated for you, because it knows where to put them.

Now, as I've mentioned before, these files aren't like what is common in Java development where each IDE has it's own set which can't be used in another, just plain and simple Ruby classes, modules, and view files.

You can create your own controllers and models etc, but the beauty of generators is you get up and running quickly. The first, and most important thing to note is you can get help on generators at any time by typing script/generate --help

All the generators are called by typing script/generate followed by the generator type and any options.

Scaffolding.

To setup your first applications, the easiest thing to do is use the scaffold generator, this not only sets up your model and controller, but a set of view files, a migration, a routes entry and some tests too.

In my application I am going to store notes, so I'll type script/generate scaffold and the name of my model which is "note", followed by it's attributes, which are a name and field type separated by a comma (e.g. name:string). Scaffolding from Rails 2.0 onwards works out the name of the controller by pluralizing the model name, pre-Rails 2.0 you had to specify the controller name separately as another parameter.

For the attributes I'll have a title which will be a string, a body which will be some text and maybe how many times it's been viewed using an integer:

title:string body:text hits:integer

You can see from the terminal that it generates a whole bunch of files, but at this moment we don't need to worry about them, we'll just migrate the database and boot up our server.

rake db:migrate script/server

We don't have anything setup for our root page at the moment, but if we go to our new controller, mine is "notes", so the URL is "/notes". You can see that we've got a list generated for us, and we can already go in and add, edit and remove notes, yet we haven't written one single line of code yet!

Now you don't always want to create all these files, sometimes you might just want a model or a controller, in which case you can simply use the script/generate command again, but you can pass model, controller, integration_test, or migration instead depending on what you want.

One thing to remember with generating controllers is that you don't actually specify the model name like in scaffold or model generations, you actually specify the controller name.

There are many more generators however, we will concentrate on them in further screencasts, scaffolding is the important one to get you one your way with development. You can look the others up using the help command I mentioned earlier if you wish.

Oops, I did something wrong!

Finally if you decide you did something you didn't want to, you can remove any changes by running the same generator but with script/destroy instead of script/generate.

Download Screencast: Mirror 1 | Mirror 2 | iPhone Size: 11.7mb, Time: 03:50

15 Rails 101: File Structure 0 comments

May 31

When starting a project Rails automatically creates a large tree structure of folders and files, so what are they all for? Find out in this screencast.

Creating a Project.

To create a project in Rails you need to be in your Terminal. Find an appropriate place to store your applications, so if you're on a Mac the "sites" folder is probably a good idea.

cd sites

You can then generate the project by simply using the "rails" command followed by the name of your project.

rails store

Once all these files have been created. You will want open them in your editor, I recommend TextMate if you're a Mac user, but anything that has a tree structure for files and ruby syntax highlighting will do.

cd store mate .

Now all these folders might be a little daunting to begin with but I'll explain them one by one. At the top we have our "app" folder, coincidently this is the folder which most of the logic behind your application will be put.

M.V.C

Rails follows the MVC (or model view controller) pattern. The way this works is it separates your code into a logical structure. Imagine a user navigates to a page on your website. Their request is first sent to the relevent controller, which picks out an action, like viewing the index, or updating an item.

The controller then loads the objects, or models it needs and maybe performs some updates on them. Models are linked to the database via ActiveRecord which means you don't really need to write any database code (such as SQL) until you're getting into advanced applications, so that is one worry you can forget about.

When the controller is finished detailing with the model it will pass on any information to the view, which will turn it into HTML, XML, RSS or whatever file format you want, before passing it back to the browser.

You might notice there is also a "helper" folder within the app directory, helpers are basically small functions you can write to save you time and tidy your code up in the views.

The Rest.

Next we have our "config" directory, this contains all the files that are run during booting your application. The most notable are your database.yml file, which stores your database access details. The routes file which basically decides what your URLs look like and maps them to the right controllers. And finally the environments folder which stores the different settings your application can run in, the defaults are development, production and test, however some people make a fourth for staging to test performance.

Your "db" directory will store the migration files you create, however they will be discussed in a separate video so don't worry about them.

The "doc" directory doesn't contain anything of significance at the moment.

You will use the "lib" directory to store custom classes for blocks functionality you've factored out of models and controllers.

One of the most important features of Rails is the log, the files store all the information you need to know while developing such as what queries are running, the performance of each page etc.

Your "public" directory is mapped to the root URL, so in plain english that means that rather than going to example.com/public/images people just visit example.com/images.

In the terminal you will run commands like script/server to boot up the server, these are all stored in the "script" directory, so you can leave that one alone for the time being.

You may have come across the acroynms TDD and BDD, which translate to test driven development and behaviour driven development. What these basically mean is that rather than waiting until the end of your project to test it, you test as you go along, so you will instantly pick up on any issues that might occur when you update your code. These tests are obviously stored in the test directory, unless you are doing BDD with Rspec - but more on that in another video.

The "tmp" directory stores your temporary files such as cache files, sessions and the like, no need to worry about that one.

Finally you have the "vendor" folder, this stores any plugins you have installed, the edge version of Rails if you're using that and any gems you have bundled into your application.

Download Screencast: Mirror 1 | Mirror 2 | iPhone Size: 22.8mb, Time: 05:01

13 Rails 101: Introduction 1 comment

May 30

What's this all about?

I'd like to introduce my new series of screencasts called "Rails 101", I realised that while Rails is really taking off, many people are put off by the lack of comprehensive beginner screencasts and the need to shell out masses of money on expensive books.

While these screencasts will be aimed at beginners, I'd hope that more advanced Rails developers will find them useful to fill gaps in their knowledge. Alongside the videos there will also be a transcript so if you don't have the bandwidth or environment to watch videos, you have an alternative.

Let's crack on with the first episode: Introduction to Rails.

We'll cover creating a project in the next screencast as there are a few things you need to hear about before you dig in to coding.

First of all there might be a little confusion with the name of Ruby On Rails, because Ruby on Rails isn't a language. Ruby is the language, Rails is just a framework built on top specifically designed for web applications. So for this reason the framework is often simply related to as Rails.

Both Ruby and Rails are open-source and cross platform, so it doesn't matter if you are running Windows, Linux or Mac OS. However it does seem to be more difficult to setup on Windows, most developers like to use Mac OS so they can use TextMate, and in Leopard Ruby and Rails are bundled as standard.

You'll spend a lot of time in the terminal or command prompt, and this might be scary at first, but it does mean you can open your documents in any text editor, and there is no need for a resource intensive IDE.

Saving time.

Gems and plugins are little bundles of code which anyone can write to share with others, so when you're looking to do something a little complicated like integrate Flickr or Twitter into your application, rather that writing loads of code, simply download a gem or plugin.

The difference between gems and plugins is that gems are available to any ruby code, whereas plugins are Rails specific, so depending on whether the bundle needs to use Rails features or not will define whether it is a plugin or a gem.

You can install gems anywhere within your system, so all you have to do is open terminal and type gem install followed by the name of the gem, whereas plugins are installed into specific Rails applications you are writing, so you need to navigate to the project and then type script/plugin install followed by the url of the plugin.

Database Connectivity.

Rails supports numerous different database types including MySQL, SQL server and Oracle, however the default is SQlite. Personally I find that SQlite for development and testing is great, but for production you want a proper database server so MySQL does the trick nicely.

In Rails 2.1 there is a database console where you can manually run SQL queries while you develop, to boot it up in your terminal simply type script/dbconsole.

Editors.

Finally, you'll see in this set of screencasts and others on the web the command "mate" followed by a full-stop commonly used in the terminal, all this does is open the current directory in TextMate, so if your editor has a similar function you can substitute it in, otherwise just open the folder manually from within your chosen application.

Download Screencast: Mirror 1 | Mirror 2 | iPhone Size: 9.8mb, Time: 03:37

20 Rails 101: Routing 2 comments

September 24

Routes define what URLs are used to access different parts of your application.

When you run the scaffold generator described in the previous screencast routes are setup for you automatically but they only setup the basics.

In this screencast, I will show you how routes work and how to set them up yourself.

How Routes Work

You'll probably hear the phrase 'RESTful routes' passed around more often than not, REST stands for Representational State Transfer and basically makes use of different types of request to process different actions, this way applications can interact with one another very easily over the standard HTTP protocol.

So how does REST affect you? Well if you are familier with HTML you will know that forms have a method attribute which is set to GET or POST, however there are actually a few more methods available to HTTP but not included in HTML, these include the PUT and DELETE methods, REST uses these to figure out whether you are trying to create, read, update or delete an item.

Create => POST /users Read => GET /users/1 Update => PUT /users/1 Delete => DELETE /users/1

The standard Rails setup needs a few more actions than these, for starters there is the index action which lists all the items in the collection, this can be accessed by GETing the collection URL, in this example at/users. Other methods by default suffix the collection URL or object URL with their name, however this behavior can be overridden - but we'll look into that later.

Index => GET /users New => GET /users/new Edit => GET /users/1/edit

Putting The Magic To Work

The routes file is located within the config directory, by default it contains just two routes, both of which aren't restful and simply act as catch all for non-nested URLs, personally I like to remove these as they let you get away with not setting up your routes properly.

To make our RESTful users section, all you need to type is map.resources :users, pretty simple right?

You can now test this with a rake command, so we'll pop open our terminal and enter rake routes, as you can see there has been multiple routes setup for us.

If you look carefully, you'll notice that each route has a name associated with it, this becomes useful in our views and controllers where we need to reference the URLs dynamically.

You can setup named routes by typing the name of your route after the word map. When setting up routes manually this way you have to specify a string which is parsed for parameters, the parameters are words prefixed with a colon, like symbols in Ruby.

For an example, I'll create a route to disable a user, the route will be called disable_user, and the route will include the user's ID, and it will call the disable method of the users controller.

map.disable_user 'users/:user_id/disable', :controller => 'users', :action => 'disable'

If we switch back to our terminal, you can see that the route is now active.

This can now be called in views and controllers as disable_user_path and disable_user_url, there is no rule for whether to use path or url, but the general consensus is that you should use ..._url in controllers, and ..._path in views.

There is one problem with our route, we were trying to match the user's ID which is a number and at the moment, it will match a word or anything upto the next forward slash, so we can add a constraint to the user id.

To do this add another symbol key to the end of the route with the name of the attribute (in this case user_id) and set it to a regular expression, if you don't know what regular expressions are, don't worry too much for now as they will be covered in a future episode. For now you can set a digit constaint using /\d/.

map.disable_user 'users/:user_id/disable', :controller => 'users', :action => 'disable', :user_id => /\d/

Remember I mentioned those additional HTTP methods before? Well we can constrain by them too, by adding the conditions hash to the end containing only one key value pair, I'll choose "PUT" which describes updating a current record.

map.disable_user 'users/:user_id/disable', :controller => 'users', :action => 'disable', :user_id => /\d/, :conditions => { :method => :put }

If you are following the restful route (no pun intended), you generally won't be writing your own routes like this very often, most of the time you can add them to the map.resources, so if we return back to our users entry, we can add our disable method to the member hash, which means it acts on one object, not the whole collection. If we wanted a disabled action to list all disabled users we can add it to the collection hash.

map.resources :user, :member => { :disable => :put }

Another bonus for using map.resources is you can easily nest resources, so for example if a user has a profile, I would nice to be able to have routes like /users/one/profile, and to save writing out massive lines of routing code, we can just change the current map.resources into a block and drop another map.resource within it, but you don't use map this time, you use the word between the goal posts, in this case 'users'.

map.resources :user, :member => { :disable => :put } do |users| users.resource :profile end

There are a few more special things to note about routes, and those are the root route (again no pun intended), path prefixing and route globbing.

When a user goes to the root URL of your site you often want users to be greeted with a homepage, or dashboard, so to do that simply create a named route called root without a URL string attached to it. In this example, I'll make it point to the index of the users controller.

map.root :controller => 'users', :action => 'index'

Path prefixing allows you to prefix resource URLs with a string such as account, this means that you can group various URLs under one section.

map.resources :user, :member => { :disable => :put }, :path_prefix => 'account'

For route globbing, or in other words catch all routes with an unlimited nesting depth (i.e /random/url/here), you can prefix the parameter with an asterisk instead of a colon and in your controller and view the parameter will return an array of the parts.

map.page '*path', :controller => 'users', :action => 'page'

Summary

To create restful routes, you can use map.resources or resource, depending on whether you want a collection, or singular resource respectively.

For the homepage you should use map.root which negates the URL option, as it defaults to an empty string.

And for other named routes you simply type map followed by the name and the URL as a string.

The options available to you are :member and :collection for adding additional actions to restful routes. There is a :conditions hash for constraints (currently :method is your only available option). For adding base urls behind restful routes use :path_prefix. :controller and action to specify what section the route relates to. And finally the attribute name (e.g. :user_id) which allows you to constrain the parameters with regular expressions.

Download Screencast: Mirror 1 | Mirror 2 | iPhone Size: 18.9mb, Time: 07:34

21 CSS Tip: Alternative Underline Colouring 0 comments

October 21

Many people aren't particularly happy with the fact that you cannot choose the colour of textual underlines in CSS, one common solution to this is to remove them and use a border below the text however this can lead to rather peculiar rendering sometimes, and often there is a more appropriate solution.

This technique isn't overly useful in body content, as it requires nested elements, but for menus it works very well. Nowadays most people use unordered lists for their menus, with each link embedded within a list item, as below:

<ul> <li><a href="#">Link One</a></li> <li><a href="#">Link Two</a></li> <li><a href="#">Link Three</a></li> </ul>

Adjusting the underline colour of the links is simple, all you need to do is remove underlining altogether from the links, and add it to the list items, this way your underline will be the colour of the list item, but the text colour will the same as the hyperlinks'.

ul li { text-decoration:underline; color:#c00; } ul li a { text-decoration:none; color:#333; }

The code above produces a link like this. You can also achieve the same effect by wrapping links in spans or visa versa, however that is not ideal.