Daniel Parker accident
on May 17, 2010 @ 01:54 AM
Daniel Parker, a colleague, friend, and coworker of mine passed away this evening. Daniel was competing in a triathlon on Friday night when he got into a biking accident. Daniel was airlifted to the University of Michigan hospital and underwent two surgeries between Friday night and Saturday, but during the second surgery they stopped because it wasn’t helping Daniel’s condition.
You may know his name if you’re a developer, because so was Daniel. You may know him from his work with Quickbooks and Ruby or maybe his GMail rubygem or one of his many other projects that he authored or contributed to.
You may know him as a Christian, because so was Daniel. While he wrote code because it was fun and he was quite good at it, he first and fore-most lived for the Lord.
You may know Daniel as a fervent competitor with a kind heart and a powerfully analytical mind. You may know Daniel for a number of other reasons, and if you didn’t know Daniel then I assure you, if you did, he would have left nothing but an impact of an honest, energetic, intelligent, warm hearted, analytical, yet loving person.
I knew Daniel because of his work in the Ruby community and in the Ruby community in the midwest and specifically Michigan. Last fall I attended GRGivecamp with Daniel. Four months ago, Daniel came and began working with me at Mutually Human Software. Daniel and I worked closely together for about 30 hours a week every week. Every day we’d pair program (or party as Daniel would call it). Almost every day we’d eat lunch together and talk – sometimes about work and sometimes about everything else in life. I never imagined that four months of my life with someone could have such an impact. That’s also the kind of person Daniel was – impactful in all the best ways.
Before I had ever met Daniel personally, my colleague John Hwang had told me that he was the kind of person we wanted to work with, not just the type of developer, but the kind of person. At first I was skeptical, but after I met and began workingw ith Daniel I knew John was right. Daniel was more then just a developer—he was human. He was the kind of spirit and person who anyone would want to build a team around. He was an amazing developer, but even more-so he was an exceptional person. It’s hard to believe that Daniel was only 23 years old.
I will miss you Daniel, as a friend, as a colleague, as a human. May your life go on to impact countless lives. I know you have impacted mine.
P.S. – when you get to heaven be sure to teach everyone Rook, they’ll love it just as much as you did when I introduced it to you. That will forever be a cherished night in my life.
activerecord-import gets basic SQLite3 and PostgreSQL support
on April 09, 2010 @ 03:44 AM
A few weeks back I started working on extracting the import functionality from ar-extensions into its own library. The initial extraction involved pulling out all of the MySQL functionality first, test by test, piece by piece. Well, tonight I pulled in the basic support for SQLite3 and PostgreSQL.
While it’s working great for MySQL, SQLite3, and PostgreSQL it has not been released as its own rubygem yet. I expect that to happen in the near-term future. In the meantime you can always check out the project on github:
In the past folks have emailed about sparse documentation. When the gem is released documentation will be provided by the github wiki ( http://wiki.github.com/zdennis/activerecord-import/ ) and the most up-to-date will be provided in the RDOC itself.
I’ve ran some benchmarks recently against MySQL 5.1 and you can find the results here: http://wiki.github.com/zdennis/activerecord-import/benchmarks
More to come!
ActiveRecord Import Updates
on March 12, 2010 @ 05:17 AM
Nearly four years ago I embarked on figuring out ActiveRecord internals enough so I could have a library which allowed me to perform bulk inserts of data in an optimized way based on the database adapter being used. Over those four years, I’ve maintained and updated the functionality with contributions from the community. A big thanks to Blythe Dunham, James Herdman, Gabe da Silveira, Thibaud Guillaume-Gentil, Marcus Crafter, and Mark Van Holstyn.
Now that Rails is nearing a 3.0 release, it’s time for to revisit this import functionality, make it compatible with the heavily refactored and cleaned up ActiveRecord internals (thx Rails core team) and add some more polished features and implementation.
The import functionality which was in ActiveRecord::Extensions is being extracted into its own library, activerecord-import. This library will be smaller and its only purpose will be to provide mass import functionality.
The work has already begun over on github: http://github.com/zdennis/activerecord-import
I look forwarding to officially releasing this in the upcoming weeks!
Summary of thoughts on data and migrations
on October 17, 2009 @ 08:16 PM
I shared a summary of my thoughts today with my project team (we’re distributed, multi-national team)... and I thought what the heck why not share with the rest of the world to. Here goes…
I’m not sure what everyone’s conventions or views are on handling the removal of data in the app that is no longer used, so here are some of the guidelines I follow to help promote sharing and consistency.
Seed data
To load data that has to exist for the application to run, I like to use seed data and I am a big fan of Michael Bleigh’s seed-fu plugin. Seed data should be setup so that it can be loaded at any point during the lifetime of an application. It should not destroy data that leaves orphaned data and it should not duplicate data.
Updating data
I like to use migrations to update existing data. If the migration and data update is complex and irreversible I will add a unit test around the migration because due to the high risk of causing irreversible damage (unless a full DB backup is loaded).
Updating application-required data
When the data that the application depends on changes (ie; the seed data) I tend to update both the seed files as well as add a migration to properly handle any existing data, whether this means removing the data, marking it as delete or inactive, etc.
Updating data
In development modifying data directly through MySQL or ruby scripts is much more forgivable and often very fast and efficient. We have no risk of causing users of the application harm or loss of data. Once something is figured out I like to either add a seed-file and/or a migration if it’s a change that needs to get made on staging and production.
In staging modifying data directly is less appealing because staging is supposed to represent what happens when we go to production. If we have to modify data directly in staging then we’ll probably have to modify it in production, so a migration and/or seed-file is a better place to track the change. I find it tempting sometimes to script/console and modify data directly.
A problem with this is that we risk screwing up staging for folks who are using it to preview features, check out bug fixes, etc. I find it better to dump the database and pull it over to my local development machine. Once I have it I can load it up locally, recreate the issue, and do whatever I need to do to find the source of the issue. This removes the risk that you fill further break staging for any users using it. Once I find the issue if I need to I will add/update a migration and/or seed file.
In production modifying data directly is super dangerous. It’s a change that occurs outside of version control and potentially without being run in development and/or staging which could catch bugs in the updates. The risk of causing irrevocable damage is so high I think doing this should be avoided.
I find it’s always been better to take an extra few minutes to make sure the fix is right and then to deploy, then it is to make a quick fix directly in production and find the change caused new issues. Production should never turn into a debugging sandbox. Pulling over a backup if necessary is safer and allows us developers more freedom to freely change the data to find the appropriate fix.
If you have to use script/console not MySQL
If you find you need to update data directly it’s better to use script/console, then by touching the database directly using MySQL. For example, Scott once asked me to change his user name. Changing his user name was a very low risk change, so I loaded up script/console and made it.
The benefit of script/console is that you let all of the rules and validations inside the application be run when you make the change. If I had made Scott’s username too short, too long, include inadmissable characters I would not find out if I did it directly through MySQL, unless I had duplicated all of the logic in MySQL stored procedures and triggers (which I cringe at the thought of).
Conclusion
Well, that’s pretty much a summary of my personal guidelines when it comes to dealing with data updates, migrations, seed-files, etc. If you have any other guidelines you follow that you find helpful please share. I think being on the same page here will help us as we push forward.
BDD not so much, really? Part II
on May 28, 2009 @ 07:38 AM
I think there’s a confusion that BDD == toolset (ie. Cucumber, Cucumber+RSpec, rspec). That needs to stop. BDD is an approach to software development. You drive your software by focusing on behaviour. This is usually done by focusing on behaviour from the outside-in. This starts by identifying the behaviour of the application, then driving inward until you get down to the low level components.
Focusing on behaviour may yield different tools throughout the process. Cucumber and RSpec are just two examples. You could very well use Cucumber plus test/unit, or perhaps just RSpec, or maybe nothing at all. These are just tools to support a development style. They are NOT the development style themselves. You can use Cucumber in a way that doesn’t support BDD. Same goes for RSpec and any other tool.
I realize there are people who don’t buy into the RSpec philosophy. To them it’s just another take on unit testing. I do buy into RSpec. From day one RSpec’s goal has been to be a BDD tool that tries to get the words right. Can you use xUnit libraries in a way to achieve the same affect? Yes you can, but most of those usages have been heavily influenced by RSpec which was built on the ideas and motivation for BDD and “getting the words right”.
Without this focus many of the high level test/unit style add-ons (especially in the ruby world like context, shoulda, test/spec, etc.) wouldn’t exist. So to me, this makes the subtle differences very important as it changed how everyone wrote their tests.
For me personally, testing is an activity after you write code. I find it refreshing to talk about writing code examples to drive design and tests to talk about actual testing. Perhaps it could be phrased as, you start with examples and when you’re done you end up with tests. Similar to starting with user stories and ending up with features. Right now that works in my head, but it’s late and I may need to revisit that thought after a few hours of sleep.
Example is just a better word then test to. When you talk to someone and you don’t understand what they’re talking about you don’t say, “give me a test”, you say, “give me an example”. Well, that language is more natural. You are providing an example of how something should work. This example ends up providing regression (test) value once its implemented, but you didn’t start with a test, you started with an example of the code you wanted.
BDD not so much, really?
on May 28, 2009 @ 06:05 AM
Updated May 29, 2009
This rant is in response to http://robertlally.com/post/bdd-not-so-much
BDD didn’t start off as a replacement for TDD. It started off a way to better understand and explain the process of TDD. The name change as I understand it was to communicate the intent of TDD in a clearer and more direct way. You’re not writing tests for the sake of writing tests, you’re driving behaviour. Focus on the behaviour you want to achieve first and foremost. Use that behaviour as the driving force for your examples (or tests).
Corey Haines nailed it on his comment to the same post, “BDD is no longer a replacement for TDD, but, rather it is a workflow for creating a system that more closely resembles what the client is looking for.” I think two of best tools which exist to support the BDD workflow of outside-in are Cucumber and RSpec. Cucumber for higher level system behaviour and RSpec for driving lower level design.
In the article, the author criticizes the “should” language. Rather than simply scoffing at the idea of replacing “assert” with “should”, I tend to think about it in terms of natural communication. The reason I like “should” language over “assert” language is that when I’m communicating with another developer I don’t say, “assert equal one day to do things good”. That doesn’t make any sense. I say, “one day to do things to should be good”. It’s much more natural for me to write closer to the language I think and communicate than it is to translate it to assertion-speak. I want to communicate in my code more closely to how I communicate to other people.
While the term BDD is a few years old it takes a while for dialogue to happen, and understanding to occur. I’m sure a lot of people hear about BDD, read about it from Dan North’s Introducing BDD . BDD started as a way to explain and better understand BDD, but what I think was realized was that it was much more than simply TDD.
Many tools are emerging which claim to support BDD-style development. It’s important to note that BDD isn’t the tool. You can have many tools support BDD style development in different ways and to different degrees. Although a good tools makes any process easier, what makes BDD is the mindset you have and how you go about writing software. Certain tools emerged with this in mind and are thus labeled BDD tools. Cucumber, RSpec, and JBehave are some examples.
The article mistakingly sheds Cucumber in the light of solely driving the design of code and suggests its a bad tool to do that. Of course it is! It is not a tool intended to drive the design of your code from a low level. It is to communicate in plain text how the application should behave. The plain text is something that is business readable, something that adds value not at the code design level, but at a higher level: communication and understanding requirements!
Cucumber is equivalent to a high level integration test for those of you who come from a testing background. It runs the entire application (or whatever can be reached through automation, different types of systems have different limitations). It works in combination with a tool used to drive out the design of your application using lower level code examples. For example, RSpec.
The #1 output of BDD is a working application that is behaving as expected. In addition to that you have an application-level regression suite in which you can run against the code base at any time. You also end up with smaller, more focused code examples which provide regression against isolated behaviour of the system.
Combined, you end up with documentation at two critical aspects. The first is business readable scenarios that the system supports. The second is developer documentation made up of the lower level code examples. Since these are often written more clearly than assert-style syntax it’s easy to produce human readable behaviour specifications for focused pieces of behaviour. And in the end you have a repeatable process which allows you to confidently produce the working software.
I also don’t see where UML to BDD comparisons make any sense. UML is a modeling language. BDD is more of an approach or methodology. A more accurate comparison would be plain text scenarios vs. UML. Although that makes little sense as a comparison because UML is not something you can give a non technical person to write, read, and edit.
BDD by itself doesn’t fix any problems. It provides an approach which focuses on behaviour first. To me, there’s no point in building a low level library if you’re not aware what higher level problem you’re solving or objective you’re adding value to. This boils down to a person still has to “do the work” to make it successful.
At the end of the day though I cannot speak for anyone else except myself. Shifting my focus on behaviour rather than “tests” led me to write better code examples. Often times I would write less of these because I was writing better examples. It’s also helped improve communication between myself and my team, customers, and other developers. BDD may evolve into something else, or perhaps a new perspective will come around that will take the world by storm. I am all about continuous learning and improvement. And I invite any ideas Mr. Lally or anyone else brings to the table.
Also, BDD never claimed to be THE answer. Any process that claims to be THE answer will surely not be THE answer for everyone in all situations. BDD has been an answer for many people though and as of now it will continue to be an answer for me in how I work.
A good resource worth checking out for BDD, it’s philosophy, and how to apply it in practice is The RSpec Book
RSpactor, love Cucumber
on April 28, 2009 @ 10:02 AM
If RSpactor loved Cucumber it’d be even more amazing. From the ticket request:
It would be amazing if RSpactor integrated with Cucumber although it would need to be a different than how it currently works with RSpec. Now that Cucumber has tag support I think this good be done in a reasonable way that improved the developer workflow for projects that utilized Cucumber. Here's an example. When I am working on changing how money is managed in my app I know that I want to run the features tagged @accounting. At the start of my work it'd be great if I could add the @accounting tag to RSpactor so it would run those features after it successfully ran specs. Perhaps there would also be a preference setting which auto ran the Cucumber scenarios after specs ran, or one that forced you to manually hit play. Although if you had typed in tags, it the play button would run cucumber with those tags.
Got a better idea for Cucumber integration? Join the discussion! http://github.com/rubyphunk/rspactor/issues/#issue/1
ar-extensions 0.8.2 released
on March 17, 2009 @ 02:09 AM
ar-extensions 0.8.2 is released. This release fixes compatibility issues with Rails 2.3.1 and Rails 2.3.2. It should show up soon at a rubygems mirror near you.
Thanks to Stephen Heuer, Glenn Rempe, and Michael Murray.
gem install ar-extensions -v 0.8.2 |
CachingPresenter has moved
on February 14, 2009 @ 11:03 PM
The new home for CachingPresenter is: http://github.com/mhs/caching_presenter
What is CachingPresenter?
CachingPresenter is a very small presenter pattern implementation in Ruby. In short, the presenter pattern is a technique used to separate presentation logic (aka display logic or view logic) from domain logic and from the view templates themselves. There are a number of reasons this pattern is beneficial when used:
- it stops presentation logic from creeping into domain objects and muddying up their implementation and their business logic
- it stops unnecessary logic from creeping into the views themselves which should be as simple, flexible, and changeable as possible
- it allows you to organize presentation logic in better ways than simply maintaining helper modules that are included everywhere
CachingPresenter seems to be benefit most web-based projects where there is benefit from a separation between the view templates and corresponding presentation logic. It works superbly with Rails, but it is not dependent on Rails. You can use it for any ruby project, web-based or not.
Recent Changes
:requiring is removed in favor of :accepts
The :requiring option has been removed in favor of :accepts. This allows all additional arguments to be optional. For example:
1 2 3 4 5 6 7 8 9 |
class NinjaPresenter < CachingPresenter presents :ninja, :accepts => [:sword, :agility] end # supplying all options ninja = NinjaPresenter.new :ninja => Ninja.new, :sword => Sword.new, :agility => 100.percent # supplying only some options, previously this would yell at you for not supplying :agility ninja = NinjaPresenter.new :ninja => Ninja.new, :sword => Sword.new |
Caches hash-reader methods
If a presenter defines the #[] method or if what is being presented on responds to the #[] methods all calls to the presenter using hash-like accessors will successfully be cached. Previously this would die.
1 2 3 4 5 6 7 8 9 10 |
class SamuraiPresenter < CachingPresenter presents :samurai, :accepts => [:stats] def [](key) @stats[key] end end samurai = SamuraiPresenter.new :samurai, :stats => { :dexterity => 80.percent } samurai[:dexterity] # => 80.percent |
Does not try to cache writer methods
Usually you don’t use writer methods on presenters, but every now and then there is a good reason. Previously, CachingPresenter would completely fail if you writer to define an writer method, now it doesn’t. And it will successfully not be cached.
1 2 3 4 5 6 7 8 |
class SamuraiPresenter < CachingPresenter presents :samurai, :accepts => [:stats] # previously this line would have failed miserably def sword=(sword) end end |
Questions / Docs / Contact / Etc
Any questions, checkout the github page and its corresponding wiki . If all else fails let me know, zach dot dennis at gmail dot com
ar-extensions 0.8.1 released
on February 10, 2009 @ 01:15 AM
ar-extensions 0.8.1 is released. This is primarily a bug fix release to ensure it works successfully with Rails 2.2.2. Here are the changes:
- fixed issue in http://zdennis.lighthouseapp.com/projects/14379/tickets/14-join-table-conditions-broken
- Updated usage of Inflector to point to ActiveSupport::Inflector
- Fixed bug where finder conditions which use arext-suffixed keys and normal field keys would fail when using a conditions hash. (Gabe da Silveira)
- added timestamps options to not automatically add timestamps even if record timestamps is disabled in ActiveRecord::Base (Thibaud Guillaume-Gentil)
- Updated to use alias_method_chain so that multiple aliased finders remain intact (Marcus Crafter)
It may take a little while for the gem to show up in the rubygem mirrors. Thanks to everyone who contributed!
ar-extensions 0.8.0, forgot to mention
on August 16, 2008 @ 02:17 PM
I forgot to mention that ar-extensions no longer loads adapter specific functionality by itself. You need to tell it what you want. For example if you want to load import functionality for MySQL you’d have to require the right files, like so:
1 2 |
require 'ar-extensions/adapters/mysql' require 'ar-extensions/import/mysql' |
Sorry about that.
ar-extensions 0.8.0 released!
on August 06, 2008 @ 07:46 PM
ar-extensions 0.8.0 is finally released! All known bugs and compatibility issues with Rails 2.1.0 have been resolved.
- 0.8.0 does not work with the latest Rails edge due to some additional features on edge that weren’t in 2.1.0
- 0.8.0 should not be used with Rails 2.0.2 or below
If any feature requests or bugs please report them on lighthouse
Installing
gem install ar-extensions |
Oracle and PostgreSQL users
If you’re using ar-extensions 0.7.0 with Oracle or PostgreSQL I am very interested to find out if 0.8.0 works fine. I don’t have Oracle, and I’m not a PostgreSQL user. If you’re interested in running the test suite against one of those databases please let me know.
Thanks for your patience and enjoy!
cheat --execute
on August 01, 2008 @ 03:21 PM
I hate having to continuously lookup the steps to install things every few weeks. The cheat gem works for most things to find installation instructions relatively quickly, but sometimes I just want to install something, not necessarily have to search through lines of example usage to find the installation instructions. Enter two new options for the cheat gem: dash x and dash dash execute. It’s simple. For example:
1 2 3 4 5 6 7 8 9 10 |
cd /some/dummy/rails/project cheat install_rspec_rails -x # This is to install the latest rspec/rspec-rails into # a rails project. script/plugin install git://github.com/dchelimsky/rspec.git script/plugin install git://github.com/dchelimsky/rspec-rails.git script/generate rspec Would you like to execute the above sheet? (Y/N) |
I’ve sent defunkt a pull request on github, I hope it includes the change. Until then, the change is only on my fork: http://github.com/zdennis/cheat/tree/master
To install do the following:
1 2 3 4 |
git clone git://github.com/zdennis/cheat.git cd cheat rake package sudo gem install pkg/cheat-1.2.2.gem |
Enjoy,
ar-extensions, Rails 2.x followup
on July 18, 2008 @ 01:41 AM
First things first, ar-extensions moved to Lighthouse and Github. So please no more tickets or patches on rubyforge. I’ll close out or move over the ones on rubyforge that currently reside there.
Now, the fun stuff.
ar-extensions and Rails 2.x compability
For the most part ar-extensions 0.7.0 (and below) is not compatible with Rails 2.0.x and 2.1. The import functionality works, but ar-extensions will bork on some edge cases of using ActiveRecord::Base.find methods. It won’t return the wrong value, it will simply raise an exception. So if you’re using ar-extensions in your Rails 2.x app, the app itself will probably bork (and I realize that you probably already know this). If you’re using the import functionality in isolation then you should be fine.
Some of the loading issues with ar-extensions that people had are due to ar-extensions being loaded during the time that Rails goes through the loading process (if you put require ‘ar-extensions’ in config/environments/development.rb, test.rb or production.rb). You can get around this by moving if after the Rails::Initializer.run block in your config/environment.rb file.
Tonight I made several commits to get ar-extensions closer to Rails 2.1.0 compatibility. HEAD right now is Rails 2.0.1 compatible, but not 2.0.2 or 2.1.0 compatible. As soon as ar-extensions is compatible I will release 0.8.0. I am hoping for it to be released within the next few days. And by compatible I mean that ar-extensions not only passes its own tests, but it also doesn’t break any of ActiveRecord’s tests.
Using Seed Data with RSpec Stories
on July 17, 2008 @ 02:29 PM
Yesterday I needed to introduce seed data into our application. In order for our story suite to continue to run I needed to populate seed data into the testing environment when the stories ran. I didn’t want to use the production seed data in my test environment, but I wanted to keep things simple. I am already using using seed_fu from Michael Bleigh to handle the seed data for production. Why not leverage it for stories as well?
I made a minor modification to the task to support passing in an argument to rake or setting an environment variable so you can load “fixtures” from a different directory. In my “stories/helper.rb” file I have added near the top:
system "rake db:seed FIXTURE_PATH=stories/fixtures" |
This loads the seed data from “RAILS_ROOT/stories/fixtures”. Here’s the modified seed_fu rake task:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
namespace :db do desc "Loads seed data from db/fixtures for the current environment." task :seed => :environment do fixture_path = ENV["FIXTURE_PATH"] ? ENV["FIXTURE_PATH"] : "db/fixtures" Dir[File.join(RAILS_ROOT, fixture_path, '*.rb')].sort.each { |fixture| puts "\n== Seeding from #{File.split(fixture).last} " + \ ("=" * (60 - (17 + File.split(fixture).last.length))) load fixture puts "=" * 60 + "\n" } Dir[File.join(RAILS_ROOT, fixture_path, RAILS_ENV, '*.rb')].sort.each { |fixture| puts "\n== [#{RAILS_ENV}] Seeding from #{File.split(fixture).last} " + \ ("=" * (60 - (20 + File.split(fixture).last.length + RAILS_ENV.length))) load fixture puts "=" * 60 + "\n" } end end |
After this my seed data was resembling the typical format:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
ExpenseCategory.transaction do ExpenseCategory.seed(:object_code) do |s| s.object_code = "1234" s.name = "Foo" end ExpenseCategory.seed(:object_code) do |s| s.object_code = "1235" s.name = "Bar" end ExpenseCategory.seed(:object_code) do |s| s.object_code = "1236" s.name = "Baz" end end |
And while I like this it’s a little verbose. So I modified seed_fu to introduce the seed_many method to consolidate that:
1 2 3 4 5 6 7 |
ExpenseCategory.transaction do ExpenseCategory.seed_many(:object_code, [ { :object_code => "1234", :name => "Foo"}, { :object_code => "1235", :name => "Bar"}, { :object_code => "1236", :name => "Baz"} ]) end |
It maintains a simple API and highly readable seed data. I’ve committed this to my fork of seed_fu, and am hoping that Michael accepts the patch and adds it to seed_fu.
- The patch for the rake FIXTURE_PATH: http://github.com/zdennis/seed-fu/commit/4d391aa214c369f161e37c194b07d49e55312b35
- The patch to add the seed_many method: http://github.com/zdennis/seed-fu/commit/9f7e8b27b7cb175911474a898ea282771ab2a5c3


