For awhile now my pet project has been running on top of the “noSQL” document database technology, MongoDB, that the folks over at 10Gen have developed. After testing the tech and going to a couple of the New York City meetups, I immediately decided to push myself to utilize this in Type Aloud. But, along with the Rails 3.0 release and Mongoid 2 (the Active Record wrapper that I am using for Mongo) I have had a hard time finding accurate up-to-date information on some less used features. One particular problem has been referencial (foreign) associations and the use of composite keys.
Because the user’s poems and stories in Type Aloud and only unique on the user level I have been unable to use a simple uniqueness validation on the document identifier which up until this point was just the default hash provided by the database. I need the composite, the user identifier and the story identifier, to be unique; I only want the user to only have one story named “Winnie the Pooh.” It may be easier to understand some code.
A standard Story model in Rails (using Mongoid) might look something like this. Notice how I do not need to explicitly provide the key because it is assumed, by default, we will use the database standard hash provided as our primary key for the document. As you see I explicitly specify the slug field as being an index as this is what will most commonly be queried. In this case, the “id” field may contain something along the lines of 4c897698cd44a10f8b000006.
class Story include Mongoid::Document include Mongoid::Timestamps include Mongoid::Paranoia include Mongoid::Versioning # Document fields field :title, :type => String field :slug, :type => String field :description, :type => String field :disabled, :type => Boolean, :default => true # Document associations embeds_many :chapters referenced_in :user # Document indicies and keys index :slug, :background => true, :unique => false # Document validators validates_presence_of :title, :description end
The problem here, and the exact reason why I merely cannot validate uniqueness on the title, is because multiple users can have the same title for a story or poem. The submissions will be presented in a vanity URL format, e.g. http://typealoud.com/johnbellone/the-darwin-prospect/chapter/1, and thus will almost always be queried with the user’s name. My solution to making this unique is quite simple. So now the story identifier will be in the format of the-darwin-prospect-4c892963cd44a108a2000008 where that hash at the end is the user’s identifier.
class Story include Mongoid::Document include Mongoid::Timestamps include Mongoid::Paranoia include Mongoid::Versioning # Document fields field :title, :type => String field :slug, :type => String field :description, :type => String field :disabled, :type => Boolean, :default => true # Document associations embeds_many :chapters referenced_in :user # Document indicies and keys key :title, :user_id # Document validators validates_presence_of :title, :description end
This works as expected and I no longer get duplicate documents. The only issue that I am having right now is Mongoid does not seem to be correctly throwing for a second save which seemingly just creates another version with a timestamp in the future. Merely adding an explicit validator does not seem to help either. Other than that this solution seems to be up to snuff, but as always, I am sure there may be a more elegant way to handle this. Any thoughts?
After work each night for the past couple of months I have been getting my hands dirty with Ruby/Rails development. I can imagine that most developers out there grow to love rake, but for the life of me I literally hate executing a series of commands on a regular basis. The programmer in me loves automation, and while in development I find myself dropping, re-creating and migrating the database constantly. Why should I have to issue three commands?
rake db:drop rake db:create rake db:migrate
After a little bit of searching I found that this can be accomplished in two commands.
rake db:reset rake db:migrate
Welp, that’s not enough for me because I am just that damn lazy. So, a simple rake task to bounce a database.
namespace :db do
desc "Drop, create and migrate the current database"
task :bounce => :environment do
Rake::Task['db:reset'].invoke
Rake::Task['db:migrate'].invoke
end
end
I hope you enjoy it as much as I do.
rake db:bounce
On my way home from work I started to put some mind power towards figuring out a solution to the issue of adequate class loading in C++. A quick Google search for “Classloading C++” brings up a few pages that are of quite an interest. You see for awhile now I have been trying to grasp why I have not found any model view controller frameworks written in C++ running on top of FastCGI, and one of the reasons that I have been stuck on is the fact that people do not want to modify, compile, start, execute in order to get through one series of tests for Internet projects. Of course, there are many ways to divide your project up appropriately to limit the compile time of certain small pieces, but in the end, there is still that dependency on the fact that we’re still shit slow compared to Ruby development.
One of the features I love about Ruby on Rails is the fact that there are long periods of time that I really never need to restart Mongrel while developing. I have my Emacs buffer pointed to a couple of files, save out my changes and click the refresh button on Chrome. That’s how easy it is. Could we achieve that development speed with a C++ framework? My my rain soaked walk home I went through it all in my head, and I firmly believe that speedy Web development with a proper C++ framework is achievable. But something core to this, at least as I see it, would be a structured dynamic class loading architecture which would allow on-the-fly loading and unloading of linked objects. In “development” mode (which could merely be controlled by an environment variable) we could even execute g++ each and every time we have a web request as long as the dependencies for these plugins were small enough to minimize compile/link time. A class loader could be pointed to a directory similar to class path environment variables, setup to look for a specific string through a regular expression, and dynamically load object files based upon the timestamp of the file. The core framework would need to be a shared library – so your classes to handle the variety of software patterns you decide to use (Observer, Singleton, MVC, etc) would be something that you’d need to take down the whole server if updated. But once a framework is to a certain point you rarely make changes to the core.
After I worked through these thoughts on the PATH ride into Harrison I got to thinking: because we have access to literally all the low level libraries for Ruby, Python, PHP, what is stopping us from building a framework that will allow simultaneous development in any language that we can plug in easily? Of course, I do not see why anyone would want to do this inside of a real development environment when you could just as quickly (and easily) stick to a single language, but the thought still piqued my interest.
Just something on my mind.