Indexes help make your database reads faster, but has the downside of making your database writes slower. Either way, you will come across the need for indexes at some point.
Mongoid has a flag called autocreate_indexes. This flag tells MongoDB to create the indexes every time a class is loaded. This is set to false by default. However, when you add an index to a model, your application will complain since there is no index in MongoDB yet.
To get around this, you can set autocreate_indexes to true. You only want to do this for development and test since this can be slow. For staging and production, you will need to log into MongoDB and create an index manually before pushing your code.
Sunday, December 12, 2010
Thursday, November 18, 2010
RSpec 2: #raise_error
I was writing a spec and attempted to use #raise_error. To my surprise, it wasn't working. Here's what I did and how I solved it.
Code to be tested:
Spec:
To my surprise, the error wasn't caught and it failed with a raised error. There was no syntax error and the way I wrote it felt very natural, but it wasn't behaving the way I thought it should. However, upon further investigation, I realized the usage of #raise_error is on a Proc or lambda.
The spec should have been:
And if you really want it to read well:
Code to be tested:
class TestClass def run; raise "Error"; end end
Spec:
it 'should raise' do TestClass.new.run.should raise_error end
To my surprise, the error wasn't caught and it failed with a raised error. There was no syntax error and the way I wrote it felt very natural, but it wasn't behaving the way I thought it should. However, upon further investigation, I realized the usage of #raise_error is on a Proc or lambda.
The spec should have been:
it 'should raise' do
Proc.new { TestCase.new.run }.should raise_error
lambda { TestCase.new.run }.should raise_error
end
And if you really want it to read well:
it 'should raise' do
expect { TestCase.new.run }.to raise_error
end
Thursday, November 11, 2010
Fixing Ruby on Ubuntu
Before using RVM, I was using the default Ruby installation on Ubuntu. Then, I needed different versions of Ruby and started messing around with installing other Rubies. Apparently, I messed up my default Ruby install without knowing it. Then, I moved off to RVM and never looked back.
Recently, I needed my system Ruby again. This is when I found out it was completely messed. It kept giving me this error when I tried to use RubyGems.
This was supposed to be impossible since thread is in the core library of Ruby. Then, I tried other things like requiring pp and date. Both gave me the same error.
I attempted to reinstall Ruby.
Unfortunately, this didn't help at all. I tried this several times to no avail. I then tried installing RubyGems through the source, but I couldn't even run setup.rb since it requires core libraries.
I decided to look through Synaptic Package Manager for anything that matched Ruby. That's when I realized I hadn't uninstalled all of Ruby. I had missed the Ruby libraries! Duh! I had messed up my Ruby libraries and wasn't reinstalling it.
This fixed my require problems and all was right again.
Recently, I needed my system Ruby again. This is when I found out it was completely messed. It kept giving me this error when I tried to use RubyGems.
'require': no such file to load -- thread (LoadError)
This was supposed to be impossible since thread is in the core library of Ruby. Then, I tried other things like requiring pp and date. Both gave me the same error.
I attempted to reinstall Ruby.
sudo apt-get purge ruby ruby-dev ruby1.8 ruby1.8-dev rubygems rubygems1.8 sudo apt-get install ruby ruby-dev rubygems
Unfortunately, this didn't help at all. I tried this several times to no avail. I then tried installing RubyGems through the source, but I couldn't even run setup.rb since it requires core libraries.
I decided to look through Synaptic Package Manager for anything that matched Ruby. That's when I realized I hadn't uninstalled all of Ruby. I had missed the Ruby libraries! Duh! I had messed up my Ruby libraries and wasn't reinstalling it.
sudo apt-get purge libruby libruby1.8 sudo apt-get install libruby
This fixed my require problems and all was right again.
Friday, November 5, 2010
Brother HL-2170W: Installation Gotchas + Reset to Factory Settings
Using Ubuntu 10.04, I decided to install this brand new printer and enable wireless printing. If you are using a USB cable, just plug-and-play. It just works. If you are planning to use wireless, read on!
Network Cable
You will need an extra network cable if your computer doesn't have wireless.Wireless Authentication
The first gotcha is wireless authentication. This printer seems to behave properly only with AES encryption. TKIP will not work. Go ahead and change your settings from your router. I'll wait.Wireless Setup
Get hold of a Windows or Mac machine. You NEED this in order to setup wireless. Ubuntu does not have an interface to this part of the printer. Unfortunately, you will need the CDs that come with the printer as well. Plop the CD into your computer and run it. A wizard will show up. It's pretty straightforward until you get to the "Top Menu". Here, you need to click the following:- Install Printer Driver (even though we just want to setup wireless)
- Wireless Network users (window pops up)
- Wireless Setup Only
- Step by Step install
From here, follow the rest of the wizard. It should detect your printer and allow you to configure settings such as IP address (if you decided to use static IP) and wireless authentication. Fill it all in. At the end, it will tell you to unplug the network cable from the printer and ask if you want to print the settings. Make sure you print the settings. If anything goes wrong, it tells you on the print-out. When I wasn't using AES encryption, I had "Failed To Associate" under "Wireless Link Status".
MAC Addresses
If you do anything with MAC addresses, the second gotcha is that the wired interface and the wireless interface have different MAC addresses. Be careful that you use the wireless one.
Ubuntu
Time to add the printer! Go to System > Administration > Printing > Add. Wait for a little bit. The New Printer popup should automatically detect your printer. Here's the third gotcha. I saw two. One that said "LPD network printer via DNS-SD" and one where it asked for Host (Probe) and Queue. You must select the DNS-SD one. The other one doesn't work! After selecting DNS-SD, it should look for drivers and then ask to print a test page. Make sure the test page prints.
Done!
Reset to Factory Settings
In case you screw up the settings and can't access the printer anymore, you can reset it to factory settings.
- Turn off the printer using the switch on the side.
- While holding down the Go button (big button that lights up blue in the corner), turn the switch on.
- Hold the Go button until the Toner, Drum, and Error lights turn on (this may be immediate).
- Let go of the Go button.
- Wait for the Toner, Drum, and Error lights to turn off (this may be immediate).
- Press the Go button 7 times.
- The Toner, Drum, and Error lights should light up after the 7th time. This means the printer has been reset to factory settings.
Monday, October 25, 2010
Rails 3.0: MongoDB + Mongoid
Why Mongoid?
The de facto ORM for MongoDB in Rails is Mongo Mapper, so why choose Mongoid? You can ready why straight from the horses mouth here.To summarize, Mongoid is built for Rails 3.0 and it handles larger documents better. It also feels like NoSQL when you use it. MongoMapper was built during Rails 2.x days and when MongoDB was young. It is modeled very closely to ActiveRecord to make the transition easier. Hence, it feels more like SQL. MongoMapper is more extensible though with a larger community.
MongoDB
Grab the latest build from MongoDB's download page. At this time, it is 1.6.3.Download and install. We make a softlink. This way, if we upgrade, we just switch the softlink and everything else stays the same.
cd /usr/local/src/ sudo wget http://fastdl.mongodb.org/linux/mongodb-linux-i686-1.6.3.tgz sudo tar xzf mongodb-linux-i686-1.6.3.tgz sudo rm -rf mongodb-linux-i686-1.6.3.tgz sudo ln -s mongodb-linux-i686-1.6.3 mongodb
Add /usr/local/src/mongodb/bin to your path.
PATH=$PATH:/usr/local/src/mongodb/bin
Make /data/db and give ownership to your user. There are obviously several ways to do this, but this is the easiest.
sudo mkdir -p /data/db sudo chown -R wesley:wesley /data
Start your engines!
mongod
Mongoid
This builds on top of my previous post on installing Rails 3.0 with BDD. This assumes that the Rails application was created without ActiveRecord using -O. Check out Rails 3.0 agnosticism for an explanation.Add mongoid to Gemfile. bson_ext is installed for a speed boost.
gem 'mongoid', '2.0.0.rc.6' gem 'bson_ext', '~>1.2'
Install mongoid.
bundle install rails generate mongoid:config
Cucumber
Add a cucumber environment to mongoid.yml.cucumber: <<: *defaults database: myproject_cucumber
Cucumber makes use of Database Cleaner. There are posts saying Database Cleaner doesn't work with Mongoid. However, it seems like it is now according to the official documentation. We need to modify features/support/env.rb this is not recommended as it is regenerated on a cucumber-rails upgrade. Instead, we will create features/support/local_env.rb.
require 'database_cleaner'
DatabaseCleaner.strategy = :truncation
DatabaseCleaner.orm = "mongoid"
Before { DatabaseCleaner.clean }
RSpec 2
RSpec includes ActiveRecord specific lines in spec/spec_helper.rb. You need to comment out the following 2 lines.# config.fixture_path = "#{::Rails.root}/spec/fixtures"
# config.use_transactional_fixtures = true
To properly clean the database, RSpec needs to know how to do that with Mongoid. Again, we can use Database Cleaner for this.
Open up spec/spec_helper.rb and add the following in the RSpec.configure block
RSpec.configure do |config|
# Other things
# Clean up the database
require 'database_cleaner'
config.before(:suite) do
DatabaseCleaner.strategy = :truncation
DatabaseCleaner.orm = "mongoid"
end
config.before(:each) do
DatabaseCleaner.clean
end
end
References
Updates
December 2, 2010: Changed Cucumber local_env.rb for database cleaning.December 2, 2010: Added a section for RSpec database cleaning.
February 1, 2011: Updated Mongoid version in the Gemfile
February 26, 2011: Added a note to clean out ActiveRecord specific lines in RSpec.
Tuesday, October 19, 2010
Rails 3.0: Installing Cucumber + RSpec 2 + Capybara + AutoTest
Behaviour Driven Development (BDD) was created in response to Test Driven Development (TDD). TDD had brought the idea of testing to the forefront, but stopped short when it was applied mainly to developers. It failed to include other stakeholders. BDD is suppose to remedy this by specifying the behaviour of the application at a high level in English. This allows non-developers to spec out the application and be included in the conversation.
Open Gemfile and add the following.
Install the gems. If you aren't using ActiveRecord, you won't have a database.yml. cucumber:install will complain unless you pass -D to it.
AutoTest checks your entire project for changes. When tests fail, test.log is written to and because there is a change, AutoTest will kick-off again, and again, and again. To stop this from happening, create a .autotest at the root of your project to ignore certain files.
AutoTest does not run Cucumber out of the box. There is debate whether autotesting Cucumber is a good idea since it is a very high-level test and can be quite heavy. Autotests should run quickly. If you want autotesting of Cucumber, you must add AUTOFEATURE to your environment before running or in your .bashrc.
Start continuous testing. Hit ctrl+c twice to stop.
Cucumber
Cucumber is a BDD framework for Ruby. Specs will be written at this higher layer first to drive behaviour.RSpec 2
RSpec 2 just came out of beta. It is a TDD framework for Ruby. Specs will be written at this second layer for testing the details of the implementation.Capybara
Capybara is a replacement for Webrat. It is used to simulate how a real world user would interact with your application. A good post about why you would use Capybara over Webrat can be found here.AutoTest
AutoTest runs your Cucumber and RSpec specs automatically whenever a file that affects the specs is modified.Install
This builds on top of my previous post on installing Rails 3.0. This assumes that the Rails application was created without Test::Unit using -T. Check out Rails 3.0 agnosticism for an explanation.Open Gemfile and add the following.
group :development, :test do gem 'capybara' gem 'database_cleaner' gem 'cucumber-rails' gem 'cucumber' gem 'rspec-rails' gem 'autotest' gem 'spork' gem 'launchy' end
Install the gems. If you aren't using ActiveRecord, you won't have a database.yml. cucumber:install will complain unless you pass -D to it.
bundle install rails generate rspec:install rails generate cucumber:install --rspec --cabybara
AutoTest checks your entire project for changes. When tests fail, test.log is written to and because there is a change, AutoTest will kick-off again, and again, and again. To stop this from happening, create a .autotest at the root of your project to ignore certain files.
Autotest.add_hook :initialize do |at|
%w{ .git doc log tmp vendor }.each { |ex| at.add_exception( ex ) }
end
AutoTest does not run Cucumber out of the box. There is debate whether autotesting Cucumber is a good idea since it is a very high-level test and can be quite heavy. Autotests should run quickly. If you want autotesting of Cucumber, you must add AUTOFEATURE to your environment before running or in your .bashrc.
export AUTOFEATURE=true
Start continuous testing. Hit ctrl+c twice to stop.
autotest
References
Updates
Feb. 8, 2011: Added solution to AutoTest continuously running on failure.Monday, October 18, 2010
Rails 3.0: Agnosticism
When Rails and Merb merged, agnosticism was one of the big features to be added to Rails. They have stayed true to this vision.
Take a look at the help when creating a new Rails application.
You will notice three options.
This allows you to create a fresh Rails application and have it ready to integrate with other gems more easily.
Take a look at the help when creating a new Rails application.
rails new --help
You will notice three options.
- -O: Skip Active Record
- -T: Skip Test::Unit
- -J: Skip Prototype
This allows you to create a fresh Rails application and have it ready to integrate with other gems more easily.
rails new myproject -OTJ
Subscribe to:
Posts (Atom)