• Category Archives: development

Ruby on Rails is like IKEA…whaa?

Recently, I found reading an article by Paul Venezia titled, Fatal abstraction: A bottom-up view of high-level languages, where—if you read between the lines—you can see that Paul just found himself waking up from a coma and it’s no longer 2004.

“I may have questioned Perl’s future now and then, and Perl certainly doesn’t have the presence it once enjoyed, but the strength of Perl has always been its flexibility. You can do pretty much anything with Perl, and you can do it in a wide variety of ways. Perl’s core revolves around the idea that there’s always more than one way to do it. In fact, there may be dozens of ways to do it. PHP shares a similar trait in that it gives you a large set of tools and leaves the construction up to you.

Ruby, and especially Rails, is the opposite, and Python definitely leans more in that direction. Essentially, it’s the difference between building a chair from raw lumber and assembling one from IKEA. This isn’t to say there’s anything wrong with assembling from parts, and clearly Ruby and Python are very capable and strong languages. However, they’re not my cup of tea.”

Admittedly, perhaps I’ve been in drinking the “kool-aid” for far too long, but I thought this tired argument has run it’s course.

I take huge offense to comparing Ruby on Rails to IKEA furniture. It’s far easier to build a web application with Ruby on Rails than it is to build an IKEA bookshelf

“When it comes right down to it, I need to know exactly what my code is doing. I’m going to keep an open mind and spend more time on the other side of the fence in the short term. Perhaps I’ll be won over, but it won’t be easy. Trust issues are complicated.”

Paul, I completely understand where you’re coming from. It sounds like you’re dealing with similar trust issues that I had nearly a decade ago. Trust me, it will be okay.

Ruby on Rails isn’t magic. Behind the curtain you’ll find a collection of object-oriented code written in one of the most readable languages in existence.

Read more at the source

Ruby on Rails developers in New York

We’ve had a number of clients in New York over the years. After a recent trip this last fall to visit clients and attend Cultivate we decided that we should spend more of our time in the city.

In 2014, we’re looking to expand our client base there. If you’re in the NYC area and are looking for an agency that has great Ruby on Rails developers… get in touch.

Read more at the source

oh-my-zsh reaches over 500 contributors

Earlier today, I noticed that we now have over 500 developers from around the globe who I have accepted pull-requests from1. That is so fantastic.

Thanks to each and every one of you who has helped make this project so wonderful for others. :-)

1 This number could be a lot higher if I spent more than a hour or two a week on this, but I’m a big fan of slow and steady… a good number of the open pull-requests are themes at the moment.

Read more at the source

Reducing MySQL’s memory usage on OS X Mavericks

Recently, I found myself re-installing everything from Homebrew and began to notice that MySQL was consuming nearly half a gig of memory. Given that I don’t do too much with MySQL on a regular basis, I opted to override a handful of default configuration options to reduce the memory footprint.

As you can see, a fresh MySQL install via homebrew was consuming over 400mb of memory.

Here is how I reduced my memory footprint:

$ mkdir -p /usr/local/etc

Unless you already have a custom MySQL config file, you will want to add one into this directory.

$ vim /usr/local/etc/my.cnf

We’ll then paste in the following options into our file… and save it.

  # Robby's MySQL overrides
  [mysqld]
  max_connections       = 10

  key_buffer_size       = 16K
  max_allowed_packet    = 1M
  table_open_cache      = 4
  sort_buffer_size      = 64K
  read_buffer_size      = 256K
  read_rnd_buffer_size  = 256K
  net_buffer_length     = 2K
  thread_stack          = 128K

Finally, we’ll restart MySQL.

$ mysql.server stop

If you have MySQL setup in launchctl, it should restart automatically. After I did this, my MySQL instance was now closer to 80mb.

So far, this has worked out quite well for my local Ruby on Rails development. Mileage may vary…

Having said that, how much memory are you now saving?

Read more at the source

GoogleAnalyticsProxy – now minified

It’s been several years since I released GoogleAnalyticsProxy, which allows our team to test their GA event/click/view tracking during the development phases of our project. Today, I pushed a quick update to it with a minified version of the JavaScript so that there is a smaller footprint.

For more information on how we use it, read my older post, Tracking Google Analytics events in development environment with GoogleAnalyticsProxy.

Read more at the source

Sending email: Controllers versus Models

While reviewing some code recently, I came across controller code that resembled the following.

if @customer.save
  CustomerMailer.deliver_welcome_message(@customer)
  flash[:message] = "Your account has been successfully created. We've sent you a welcome letter with..."
  redirect_to dashboard_path
else
  ...
end

Fairly typical Rails code. Nothing alarming here, but I wanted to evaluate the call to the mailer in this scenario. When it comes to sending emails from your application, you can choose to do it from the controller as in the example above or in your models. Our team prefers to do this from our model via a callback as we are considering this to be part of our business logic.

Each time a customer is created, we want to send them an email. This can be moved into the model and resembled something like the following..

after_create :send_welcome_message #, other callbacks..

def send_welcome_message
  CustomerMailer.deliver_welcome_message(self)
end

There are a few benefits to doing it this way.

  1. We can test that this is being triggered within our model specs instead of our controller specs. (we prefer to spend more of our time working within models than controllers)
  2. We remove the dependency that all requests must be processed through our controllers.
    • Example: We may one day create rake tasks that data and want these emails to still be sent out. (We’ve had to do this a few times)

I definitely don’t think doing this via controllers is a bad idea, I just lean towards keeping controllers as dumbed down as possible. This allows us to have less controller code that is focused on passing data to/from models and letting our models do the heavy lifting.

UPDATE: DHH was kind enough to post a more detailed response on his blog.

Read more at the source

Using BETWEEN for SQL comparisons

Recently, Carlos, suggested that I should start sharing some basic SQL tips that help with performance and/or general usage. I recently came across some code that I didn’t like to read and/or write. For example, let’s take the following…


SELECT * FROM brochures WHERE published_at <= now() AND archived_at >= now()

Essentially, this is pulling back some data WHERE the the brochures are considered published. (We have a project that allows people to manage their brochure launch dates ahead of time.) In fact, in this project, we have no less than 6-8 dates in the database that we’re comparing data on and it’s easy to get lost in the logic when trying to understand it.

Now, there isn’t anything inheriently wrong with how this condition is constuctued. As a matter of personal taste, I find it annoying to mentally parse. Also, I find having to write now() more than once in a WHERE clause to feel like I’m repeating myself.

Read it outloud…

“WHERE the brochures published at date is less than and/or equal to right now AND the archived date is greater than and/or equal to now.”

Who talks like that?

Luckily, there is a better and in my opinion, a more readable way to express this is with the BETWEEN construct in SQL. (postgresql docs, mysql docs)


SELECT * FROM brochures WHERE now() BETWEEN published_at AND archived_at

Let’s read this outloud…

“WHERE the current date is between the published at and archived at dates.”

This sounds more natural to me.

Additionally, you can also do the inverse with NOT.


SELECT ... WHERE now() NOT BETWEEN brochures.published_at AND brochures.archive_at

Remember kids, “code is for humans first and computers second.”—Martin Fowler

Read more at the source

Launching Ruby on Rails projects, the video

For those of you who didn’t make it to Rails Underground in July to witness my mind-blowing talk, Launching Ruby on Rails projects , it appears that Skills Matter has finally posted a video of it online. :-)

The sound levels are really low… but hopefully you’ll find it helpful.

You can also view the slides.

Related Posts

Read more at the source

Flash Message Conductor now a Gem

We’ve been doing some early (or late… if you’re a half-full kind of person) spring cleaning on some of our projects. One of the small projects, flash_message_conductor, which we released last year as a plugin is now a gem. We’ve been moving away from using plugins in favor of gems as we like locking in specific released versions and being able to specify them in our environment.rb file is quite convenient.

To install, just run the following:


  sudo gem install flash-message-conductor --source=http://gemcutter.org
  Successfully installed flash-message-conductor-1.0.0
  1 gem installed
  Installing ri documentation for flash-message-conductor-1.0.0...
  Installing RDoc documentation for flash-message-conductor-1.0.0...

You’ll then just need to include the following in your config/environment.rb file.

Rails::Initializer.run do |config|
  # ...
  config.gem 'flash-message-conductor', :lib => 'flash_message_conductor', :source => "http://gemcutter.org"
end

You can take a peak at the README for usage examples.

We’ll be packaging up a handful of our various plugins that we reuse on projects and moving them to gems. Stay tuned… :-)

Read more at the source

Planting the seeds

Yesterday, the Rails team released 2.3.4, which includes standardized way for loading seed data into your application so that you didn’t have to clutter your database migrations.

I noticed a few comments on some blogs where people were asking how to use this new feature, so here is a quick runthrough a few ways that you can use it.

Populating Seed Data Approaches

The db/seeds.rb file is your playground. We’ve been evolving our seed file on a new project and it’s been great at allowing us to populate a really large data. Here are a few approaches that we’ve taken to diversify our data so that when we’re working on UI, we can have some diversified content.

Basic example

Any code that add to db/seeds.rb is going to executed when you run rake db:seed. You can do something as simple as:

# db/seeds.rb

Article.create(:title => 'My article title', :body => 'Lorem ipsum dolor sit amet, consectetur adipisicing elit')

Just create database records like you would in your Rails application or in script/console. Simple enough, right? Let’s play with a few other approaches that we’ve begun to use.

Use the names of real people

We’re using the Octopi gem to connect to github, collect all the names of people that follow me there, and using their names to seed our development database.

@robby_on_github = Octopi::User.find('robbyrussell')

# add a bunch of semi-real users
@robby_on_github.followers.each do |follower|
  github_person = Octopi::User.find(follower)
  next if github_person.name.nil?

  # split their name in half... good enough (like the goonies)
  first_name = github_person.name.split(' ')[0]
  last_name = github_person.name.split(' ')[1]
  new_person = Person.create(:first_name => first_name, :last_name => last_name, :email => Faker::Internet.email,
                             :password => 'secret', :password_confirmation => 'secret',
                             :github_username => follower, :website_url => github_person.blog)
  # ...
end

We do this with a few sources (twitter, github, etc..) to pull in the names of real people. If you want to be part of my seed data, you might consider following me on Github. ;-)

Use Faker for Fake data

You may have noticed in the previous code sample, that I used Faker in that code. We are using this a bunch in our seed data file. With Faker, you can generate a ton of fake data really easy.

person.links.create(:title => Faker::Lorem.words(rand(7)+1).join(' ').capitalize,
                    :url => "http://#{Faker::Internet.domain_name}/",
                    :description => Faker::Lorem.sentences(rand(4)+1).join(' '))

We might toss something like that into a method so that we can do the following:

@people = Person.find(:all)

500.times do
  generate_link_for(@people.sort_by{rand}[0])
end

…and we’ll get 500 links added randomly across all of the people we added to our system. You can get fairly creative here.

For example, we might even wanted random amounts of comments added to our links.

def generate_link_for(person)
  link = person.links.create(:title => Faker::Lorem.words(rand(7)+1).join(' ').capitalize,
                             :url => "http://#{Faker::Internet.domain_name}/",
                             :description => Faker::Lorem.sentences(rand(4)+1).join(' '))

  # let's randomly add some comments...
  if link.valid?
    rand(5).times do
      link.comments.create(:person_id => @people.sort_by{rand}[0].id,
                           :body => Faker::Lorem.paragraph(rand(3)+1))
    end
  end
end

It’s not beautiful, but it gets the job done. It makes navigating around the application really easy so that we aren’t having to constantly input new data all the time. As mentioned, it really helps when we’re working on the UI.

Your ideas?

We’re trying a handful of various approaches to seed our database. If you have some fun ways of populating your development database with data, we’d love to hear about it.

Read more at the source
close