<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss' xmlns:gd='http://schemas.google.com/g/2005' xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-3801291744763124959</id><updated>2011-11-13T00:20:05.824-08:00</updated><title type='text'>Last of the freelance hackers and...</title><subtitle type='html'></subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://modetojoy.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3801291744763124959/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://modetojoy.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>Durran Jordan</name><uri>http://www.blogger.com/profile/03648606032145065169</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://1.bp.blogspot.com/_1u25jYTeLlo/SXjxPcuN9BI/AAAAAAAAAGU/3QwgWed_kK4/S220/IMGP5917.jpg'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>3</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-3801291744763124959.post-5695183457065304997</id><published>2010-01-02T09:16:00.000-08:00</published><updated>2010-01-02T09:43:00.028-08:00</updated><title type='text'>Inheritance in Mongoid</title><content type='html'>Version 0.11.0 introduces inheritance support in Mongoid, and here's how it all fits together...&lt;br /&gt;&lt;br /&gt;Let's start with a simple domain model without any associations:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;  class Canvas&lt;br /&gt;    include Mongoid::Document&lt;br /&gt;    field :name&lt;br /&gt;  end&lt;br /&gt;&lt;br /&gt;  class Browser &lt; Canvas&lt;br /&gt;    field :version, :type =&gt; Integer&lt;br /&gt;  end&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Given the above model, my &lt;tt&gt;Canvas&lt;/tt&gt; class would be stored by default in a "canvases" collection in the database. All subclasses of &lt;tt&gt;Canvas&lt;/tt&gt; will share this collection, similar to the way Single Table Inheritance works in ActiveRecord. The underlying implementation is simple: a "_type" field is stored on the document in order for Mongoid to know what class the document is when it performs queries to retrieve them from the database.&lt;br /&gt;&lt;br /&gt;As with traditional inheritance, properties of the parent class are available on the child class, but not vise-versa. In the above case &lt;tt&gt;Browser&lt;/tt&gt; would have a field "name", but &lt;tt&gt;Canvas&lt;/tt&gt; would not have a "version" field.&lt;br /&gt;&lt;br /&gt;Querying for either is as expected:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;  Canvas.where(:name =&gt; "paper")  # Will only return Canvas documents&lt;br /&gt;  Browser.where(:name =&gt; "firefox")  # Will only return Browser documents&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Let's get into associations, and expand the above domain model to include some shapes:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;  class Canvas&lt;br /&gt;    include Mongoid::Document&lt;br /&gt;    field :name&lt;br /&gt;    has_many :shapes&lt;br /&gt;&lt;br /&gt;    def render&lt;br /&gt;      shapes.each { |shape| shape.render }&lt;br /&gt;    end&lt;br /&gt;  end&lt;br /&gt;&lt;br /&gt;  class Browser &lt; Canvas&lt;br /&gt;    field :version, :type =&gt; Integer&lt;br /&gt;  end&lt;br /&gt;&lt;br /&gt;  class Shape&lt;br /&gt;    include Mongoid::Document&lt;br /&gt;    field :x, :type =&gt; Float&lt;br /&gt;    field :y, :type =&gt; Float&lt;br /&gt;    belongs_to :canvas, :inverse_of =&gt; :shapes&lt;br /&gt;&lt;br /&gt;    def render; end&lt;br /&gt;  end&lt;br /&gt;&lt;br /&gt;  class Circle &lt; Shape&lt;br /&gt;    field :radius, :type =&gt; Float&lt;br /&gt;  end&lt;br /&gt;&lt;br /&gt;  class Rectangle &lt; Shape&lt;br /&gt;    field :width, :type =&gt; Float&lt;br /&gt;    field :height, :type =&gt; Float&lt;br /&gt;  end&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Now we have an embedded collection of shapes that will be stored in the canvas or browser documents. We can add shapes in the normal manner:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;  browser = Browser.new(:name =&gt; "firefox")&lt;br /&gt;  circle = Circle.new(:x =&gt; 0, :y =&gt; 0, :radius =&gt; 20)&lt;br /&gt;  rectangle = Rectangle.new(:x =&gt; 5, :y =&gt; 10, :width =&gt; 100, :height =&gt; 50)&lt;br /&gt;  browser.shapes &lt;&lt; [circle, rectangle]&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;The resulting document when saved would resemble the following hash:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;  { &lt;br /&gt;    "_type" =&gt; "Browser",&lt;br /&gt;    "name" =&gt; "firefox",&lt;br /&gt;    "shapes" =&gt; [ &lt;br /&gt;      { &lt;br /&gt;        "_type" =&gt; "Circle",&lt;br /&gt;        "x" =&gt; 0,&lt;br /&gt;        "y" =&gt; 0,&lt;br /&gt;        "radius" =&gt; 20&lt;br /&gt;      },&lt;br /&gt;      { &lt;br /&gt;        "_type" =&gt; "Rectangle",&lt;br /&gt;        "x" =&gt; 5,&lt;br /&gt;        "y" =&gt; 10,&lt;br /&gt;        "width" =&gt; 100,&lt;br /&gt;        "height" =&gt; 50&lt;br /&gt;      }&lt;br /&gt;    ]&lt;br /&gt;  }&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;The methods #create and #build on has many and has one associations now have an additional optional parameter, the type of class to create. If not provided it will create a class that is determined by the association name:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;  browser = Browser.new(:name =&gt; "firefox")&lt;br /&gt;  browser.shapes.build({ :x =&gt; 0, :y =&gt; 0, :radius =&gt; 50 }, Circle) # Creates a Circle&lt;br /&gt;  browser.shapes.build({ :x =&gt; 0, :y =&gt; 0 }) # Creates a Shape&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;And that's it, nice and simple.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3801291744763124959-5695183457065304997?l=modetojoy.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://modetojoy.blogspot.com/feeds/5695183457065304997/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://modetojoy.blogspot.com/2010/01/inheritance-in-mongoid.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3801291744763124959/posts/default/5695183457065304997'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3801291744763124959/posts/default/5695183457065304997'/><link rel='alternate' type='text/html' href='http://modetojoy.blogspot.com/2010/01/inheritance-in-mongoid.html' title='Inheritance in Mongoid'/><author><name>Durran Jordan</name><uri>http://www.blogger.com/profile/03648606032145065169</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://1.bp.blogspot.com/_1u25jYTeLlo/SXjxPcuN9BI/AAAAAAAAAGU/3QwgWed_kK4/S220/IMGP5917.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3801291744763124959.post-4372205936350386309</id><published>2009-08-24T11:39:00.000-07:00</published><updated>2009-09-09T06:33:22.244-07:00</updated><title type='text'>Getting MongoDB running on EngineYard Cloud with Master/Slave Replication</title><content type='html'>Just recently we got MongoDB up and running on EngineYard cloud, and thought we'd share the steps to get it up and running in an automated fashion using Chef. For more on getting Chef scripts running on your instance in general, please see:&lt;br /&gt;&lt;br /&gt;&lt;a href="https://cloud-support.engineyard.com/faqs/chef/using-chef-to-customize-your-environment"&gt; https://cloud-support.engineyard.com/faqs/chef/using-chef-to-customize-your-environment&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Special thanks to John Hornbeck for the starter scripts &lt;a href="http://github.com/hornbeck/ey-cloud-recipes/tree/master"&gt;here&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;Our environment currently runs MongoDB v1.0.0 64bit for Linux. The following steps will get you up and running with master/slave replication - master will run on port 27017, the slave will run on 27018. Master data will save in /data/masterdb, and slave data will save in /data/slavedb:&lt;br /&gt;&lt;br /&gt;1. Login to your cloud dashboard at (&lt;a href="http://cloud.engineyard.com"&gt;http://cloud.engineyard.com&lt;/a&gt;).&lt;br /&gt;&lt;br /&gt;2. Click the "Extras" tab on the left side under "Server Management".&lt;br /&gt;&lt;br /&gt;3. Download your "ey-cloud.yml" API credentials.&lt;br /&gt;&lt;br /&gt;4. Copy the ey-could.yml into your local home directory.&lt;br /&gt;&lt;br /&gt;5. Install the rest-client and aws-s3 Ruby gems:&lt;br /&gt;&lt;pre&gt;    $sudo gem install rest-client aws-s3&lt;/pre&gt;&lt;br /&gt;6. Install the ey-flex Ruby gem:&lt;br /&gt;&lt;pre&gt;    $sudo gem install ey-flex --source http://gems.engineyard.com&lt;/pre&gt;&lt;br /&gt;7. Fork the durran ey-cloud-recipes repository at (&lt;a href="http://github.com/durran/ey-cloud-recipes/tree/master"&gt;http://github.com/durran/ey-cloud-recipes/tree/master&lt;/a&gt;)&lt;br /&gt;&lt;br /&gt;8. Clone the forked repo: &lt;br /&gt;&lt;pre&gt;    $git clone git@github.com:[github username]/ey-cloud-recipes.git&lt;/pre&gt;&lt;br /&gt;9. Run the following command locally:&lt;br /&gt;&lt;pre&gt;    $ey-recipes&lt;br /&gt;&lt;br /&gt;    Current Environments:&lt;br /&gt;    env: hashrocket  running instances: 1&lt;br /&gt;    instance_ids: ["i-863bd6ee"]&lt;br /&gt;    env: mongo  running instances: 1&lt;br /&gt;    instance_ids: ["i-9a7c92f2"]&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;10. The output of the command will give you your application information, including the name of your environments, you'll want to run the following next to upload the recipes to the appropriate env, where "envname" is what appeared after "env:":&lt;br /&gt;&lt;pre&gt;    $ey-recipes --upload envname&lt;/pre&gt;&lt;br /&gt;11. In your EY cloud console click on the "Deploy" link for your environment - you are good to go. Please note if your deploy has any dependency on Mongo running you will need to uncheck all boxes in the deploy modal dialog on the first deploy so only the chef scripts get run. Then each subsequent deploy can run normally.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3801291744763124959-4372205936350386309?l=modetojoy.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://modetojoy.blogspot.com/feeds/4372205936350386309/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://modetojoy.blogspot.com/2009/08/getting-mongodb-running-on-engineyard.html#comment-form' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3801291744763124959/posts/default/4372205936350386309'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3801291744763124959/posts/default/4372205936350386309'/><link rel='alternate' type='text/html' href='http://modetojoy.blogspot.com/2009/08/getting-mongodb-running-on-engineyard.html' title='Getting MongoDB running on EngineYard Cloud with Master/Slave Replication'/><author><name>Durran Jordan</name><uri>http://www.blogger.com/profile/03648606032145065169</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://1.bp.blogspot.com/_1u25jYTeLlo/SXjxPcuN9BI/AAAAAAAAAGU/3QwgWed_kK4/S220/IMGP5917.jpg'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3801291744763124959.post-1719048054428713312</id><published>2009-04-10T11:16:00.000-07:00</published><updated>2009-04-10T11:57:06.147-07:00</updated><title type='text'>Unit-Testing jQuery AJAX Calls With Screw-Unit and JSMock</title><content type='html'>The more web development I do, the more client-side heavy web applications seem to get. Over the past few years I have found myself almost exclusively using jQuery as a client-side Javascript framework, and have needed to do more unit-testing of my Javascript more and more as time progresses. One thing I have noticed though, is that unit-testing seems to get left out when dealing with jQuery AJAX calls. Well I decided this should go no further.&lt;br /&gt;&lt;br /&gt;&lt;i&gt;Note these examples are using &lt;a href="http://github.com/nkallen/screw-unit/tree/master"&gt;screw-unit&lt;/a&gt; as the testing framework, and my updated implementation of &lt;a href="http://github.com/durran/jsmock/tree/master"&gt;JSMock&lt;/a&gt; to handle equivalence matching of Javascript Objects&lt;/i&gt;&lt;br /&gt;&lt;br /&gt;Lets say for example I have an Object or class that I want to delegate to jQuery for some AJAX functionality, in this case I want it to be a sort of Javascript Controller that interacts via AJAX with my Controller on the server. For simplicity let's call it an AddressController, which (thank you captain obvious) provides me with addresses given an ID. My spec will look something like this:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;Screw.Unit(function() {&lt;br /&gt;&lt;br /&gt;  describe("AddressesController", function() {&lt;br /&gt;&lt;br /&gt;    var placeholder;&lt;br /&gt;    var control;&lt;br /&gt;&lt;br /&gt;    before(function() {&lt;br /&gt;      placeholder = jQuery;&lt;br /&gt;      control = new MockControl();&lt;br /&gt;      jQuery = control.createMock(jQuery);&lt;br /&gt;    });&lt;br /&gt;&lt;br /&gt;    after(function() {&lt;br /&gt;      jQuery = placeholder;&lt;br /&gt;    });&lt;br /&gt;&lt;br /&gt;    describe("#show", function() {&lt;br /&gt;      describe("when an id is provided", function() {&lt;br /&gt;        it("should delegate to jQuery.ajax()", function() {&lt;br /&gt;          var params = { url: "/addresses/15", success: renderAddress };&lt;br /&gt;          jQuery.expects().ajax(params);&lt;br /&gt;          AddressesController.show(15);&lt;br /&gt;          control.verify();&lt;br /&gt;        });&lt;br /&gt;      });&lt;br /&gt;    });&lt;br /&gt;&lt;br /&gt;  });&lt;br /&gt;&lt;br /&gt;});&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;My test is asserting that when I call show() on my AddressesController, I'll make a RESTful AJAX call to my controller on the server, and on success will call the renderAddress() function. The before and after setup is to restore jQuery back after I have mocked it out, so future tests that use jQuery will not break.&lt;br /&gt;&lt;br /&gt;Now for my AddressesController:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;AddressesController = {&lt;br /&gt;  show: function(id) {&lt;br /&gt;    jQuery.ajax({&lt;br /&gt;      url: "/addresses/" + id,&lt;br /&gt;      success: renderAddress&lt;br /&gt;    });&lt;br /&gt;  },&lt;br /&gt;};&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;And that's all there is to it. Note that after I did my modifications on JSMock I discovered &lt;a href="http://code.google.com/p/amok/"&gt;amok&lt;/a&gt;, which as a nicer syntax that JSMock, and is much closer to EasyMock 2/Mocha syntax without the need of MockControl objects... I'll be getting into that in the next post.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3801291744763124959-1719048054428713312?l=modetojoy.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://modetojoy.blogspot.com/feeds/1719048054428713312/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://modetojoy.blogspot.com/2009/04/unit-testing-jquery-ajax-calls-with.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3801291744763124959/posts/default/1719048054428713312'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3801291744763124959/posts/default/1719048054428713312'/><link rel='alternate' type='text/html' href='http://modetojoy.blogspot.com/2009/04/unit-testing-jquery-ajax-calls-with.html' title='Unit-Testing jQuery AJAX Calls With Screw-Unit and JSMock'/><author><name>Durran Jordan</name><uri>http://www.blogger.com/profile/03648606032145065169</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://1.bp.blogspot.com/_1u25jYTeLlo/SXjxPcuN9BI/AAAAAAAAAGU/3QwgWed_kK4/S220/IMGP5917.jpg'/></author><thr:total>0</thr:total></entry></feed>
