Customizing Twitter Bootstrap On Rails 3
Twitter bootstrap has made developers lives better. It is easy to install, fast to implement and has all the structure you could need to make a not horrible looking website. The only downside is everyone’s sites now look the same. It doesn’t have to be this way, Twitter bootstrap is also easy to customize.
The other day I came across a project called Bootswatch from Thomas Park (@thomsapark on twitter) that makes it even easier to customize your bootstrap site.
This tutorial will show you how to customize an existing rails 3 app that is already setup using the twitter-bootstrap-rails gem.
(See https://github.com/seyhunak/twitter-bootstrap-rails for twitter-bootstrap-rails gem instructions)
1. In your app/assets/stylesheets directory create a bootswatch folder
2. Download a custom look from BootSwatch.com
Select your theme and from the dropdown arrow on the download button get the variables.less & bootswatch.less files and save them to your bootswatch folder.
3. In your bootstrap_and_overrides.css.less below @import “twitter/bootstrap/responsive”;
add
@import “bootswatch/variables.less”;
@import “bootswatch/bootswatch.less”;
4. Modify application.css
change
*= require_tree .
to
*= require “bootstrap_and_overrides”
Leaving require_tree will cause your application to error out because it will include the bootswatch files twice. Once where we included it in step 3 and a second time outside the context of bootstrap. The second time is the problem because the files reference variables set in the base bootstrap install.
5. View the site in your browser and you should see the new custom look bootstrap site
What’s Going On Here
From bootswatch.com you are downloading some less files. For those that don’t know less is less gets compiled into CSS. Less is what twitter bootstrap is written in.
The less files we have added are overriding the default values in the base bootstrap files.
Specifically variables.less is reassigining the variables and bootswatch.less is changing structural elements of the layout.
If you are a designer and want to make custom Bootswatches there is a swatchmaker project on github https://github.com/thomaspark/bootswatch/tree/master/swatchmaker
Validating & Testing a MongoDB Array with Rspec and Mongoid
If you want to use geolocation in your web app, out of the box mongodb offers a pretty good set of features. The function set isn’t as full featured as layering PostGIS on top of postgres. But for what most apps seem to do with geodata mongoDB is plenty. MongoDB is good enough for foursquare then it is probably good enough for your checkin app.
Problem: In a sql database you would have a table with a column for latitude and column for longitude. Easy to validate and test. To use the geo features in MongoDB you need to store the data in a 2 item array so the coordinates can be indexed in a way mongo can take advantage of. This makes testing and validating more complicated.
What needs to be tested? First, are there 2 elements in the array? Second, are the numbers within the range of -180 to 180?
Solution: If you are working with rails and mongoDB you need replace ActiveRecord with a mongoDB specific ORM. I recommend mongoid. The guys behind mongoid used ActiveModel to handle validations. This is a very smart choice because ActiveModel is what ActiveRecord uses. Hooray consistency!
The Tests
Make Them Pass
What is happening?
In the tests the let(:golfcourse) creates the Golfcourse object I am testing against. The context is creating a grouping of tests. The first test checks that the golfcourse.loc has 2 elements in the array. The second test is checking that having only 1 element is invalid by setting the second element in the array to nil. The third test is checking if the loc element is in the range by changing the first element to a number outside the range.
To make this all work the model needs a custom validation method. The custom validation is called with the
validate :locValidations
Inside the validation the first if checks to see if the 2 array elements are there. Assuming that both are present the elsif is called checking to see if the elements are within the range. The key to custom validations is what gets returned if the validation fails.
errors.add(:what, ‘error message’)
Returning false or anything other than errors.add(:what, “message”) the validation will assume it passed and that defeats the purpose of having validations in the first place.
Low level caching is very easy to get started with in Rails 3, but it seems to be missing from the official guides. I personally use it all the time to help reduce the number of queries or API calls I’m making. Heroku has a pretty good explanation which, if you’re so far unfamiliar with…
I think there’s something messed up about the startup culture in the USA. The belief is that you have to work 6-7 days a week and spend all your mental cycles on your company. Nothing but pledging your soul to your startup yields success, right?
Not in my experience.
We work a 4-day week at …
Ruby Weekend
We have a date and location for the first Ruby Weekend.
When: Jan. 28 & 29, 2011 Where: usr/lib in downtown Vegas
The website http://rubyweekend.com will be up and running in a few days.
Tickets are $50. (There are only 24 seats available so reserve your seat asap). BONUS: all attendees will get a 1 year membership to usr/lib.
gary:
Why is raising money celebrated more than making money?
I gave a rant on a TV spot and it has caused some stir, I would love to know your 2 cents on the matter?here is a link to a business insider article http://www.businessinsider.com/why-startups-praised-for-funding-2011-10
We celebrate winners even if it is premature.
Nifty Generators and Rspec Fail
I am really digging nifty-generators. In a previous post I covered nifty:authentication and I do plan on writing up the other nifty functions shortly.
When you run nifty:scaffold it creates some basic rspec tests for you. You would imagine that being generated by the gem when you run “rspec spec/” all the tests would pass. In my case 2 tests failed.
it “create action should render new template when model is invalid” do
Chapter.any_instance.stubs(:valid?).returns(false)
post :create
response.should render_template(:new)
end
and
it “update action should render edit template when model is invalid” do
Chapter.any_instance.stubs(:valid?).returns(false)
put :update, :id => Chapter.first
response.should render_template(:edit)
end
You can see that they are both the same basic test. What is causing the error is the mock framework used in rspec. By default rspec uses rspec.
One of the gem dependencies of nifty-generators is mocha. These tests are failing because mocha is not being used as the mock framework. The solution lies in the spec_helper.rb file. Uncomment out the line for config.mock_with :mocha and comment out config.mock_with :rspec
Run your tests again and they should now all pass.
Nifty Generators and User Authentication
For a project I am working on I need a way to authenticate users. Pretty standard I know. Just about every website has and needs some form of user authentication so there are a lot of answers to the challenge.
- You can roll your own from scratch.
- You can use a 3rd party omniauth solution that allows your visitors to login through facebook or twitter.
- You can use a prebuilt auth engine like Devise or Clearance.
For this project OmniAuth is not an option. I do think there are a lot of service apps that really should use 3rd party user authentication instead of making people signup for another account.
Devise and Clearance are both acceptable solutions for a lot of projects and allow you to add user functionality quickly. The downside is they are engines and as a result a lot of the code is hidden. If you want to do things in a different way that the default install it quickly becomes a hassle. As a new developer this hassle is a deal breaker.
That leaves rolling your own. Creating a user login system is not really that difficult. There is an example in Michael Hartl’s Rails 3 Tutorial. There is an example in Agile Web Development in Rails. In Rails Cast episode #250 Ryan Bates shows you how to do it in 15 minutes.
There is actually another option for rolling your own using Nifty Generators. What makes the nifty solution so nifty is it generates all the code in your app. This means unlike the engine solutions the code is in front of you and ready to be manipulated.
Getting Started
In rails 3 you need to add nifty-generators to your gemfile
gem ‘nifty-generators’
Don’t forget to run “bundle install” before moving on to the next step.
With nifty-generators now in your application run
rails g nifty:authentication
It will create your user model or append your existing one by adding the necessary fields and generates the migration file accordingly. It also creates the signup and login views. Run rake db:migrate and you have a basic authentication system. What you do next is up to you.
New to ROR Resources
1. Learn to Program by Chris Pine
If you are brand new to programming this is a great starting point. It covers the basics of the ruby language and you get to start making things that do stuff immediately. This is a short book and if you are motivated you can go cover to cover in just a couple of days.
This book is for the absolute beginner. If you are coming from another language this book is probably not what you are looking for. You would be better served with Programming Ruby (#5 on this list).
- Website: http://pine.fm/LearnToProgram/
- Book: http://amzn.to/learn2program
2. Rails For Zombies
Rails for Zombies is the free introductory course to Ruby on Rails from Code School. Code School produces high quality screen casts and after each section there is an interactive code quiz that reinforces the lesson. Downloading the show notes is really helpful in passing the section quizzes.
3. Ruby on Rails 3 Tutorial by Michael Hartl
Do you want to jump in and build something significant? How about building a fully functioning twitter clone? The Ruby on Rails 3 Tutorial takes you through start to finish on building a micro-blogging web app. The author Michael Hartl focuses on not just slapping a bunch of code together. This book uses Test Driven Development (TDD) to make sure that you are building something that works.
4. Rails Best Practices
Rails best practices is another Code School class. This dives deeper in to not just writing code but making the code better through the use of convention.
5. Programming Ruby by Dave Thomas
Affectionately known as Pick Axe because of the picture on the cover. Programming Ruby is considered the book on ruby. At almost 900 pages it is a monster. Luckily it is not designed to be a cover to cover page turner. The first half of the book is about how to use the ruby language and the second half is a reference guide. This is a must have for all serious ruby-ist.