uncommon is alive

uncommon is alive!

I’m proud to have had a part in the inception of this project, though other responsibilities prevented me from taking a larger role in helping to create it. I hope I’ll be able to contribute some more in the future.

You can see what it’s all about here:

Uncommon in Common is the online home for a community of kind and curious people like you, a front porch for the Internet. It’s a place to share our favorite things and the best parts of our week, a place for meaning and wonder.

Right now, it’s only open to the founding members, people who joined the mailing list and made a small contribution early on in the project’s history. As I understand it, soon each member will be able to invite another soul for a year’s membership. At some point (I’m not sure when?), it will open up for membership. Stay tuned. It’s going to be a wonderful thing.

Refactoring with code blocks in Ruby

I came across this situation the other day. I had a method which already existed on one model: let’s say it ran through all of that models associations and did a thing, a notification, for example.

class Group < ActiveRecord::Base
    def notify_members
        members.each do |member|
            member.notify
        end
    end
end

Seems okay. Turned out, I had another method, somewhere else, which also wanted to notify all the groups members–but it also wanted to do a little more logging. Let’s say, something bad happened: we need to put the Group in a different state, and then not only notify all the members, but do some logging. This is logging that we don’t need to do in the normal notify_members method. We could duplicate behavior:

def notify_members_with_logging
    members.each do |member|
        member.notify
        Alert.create(:member => member, :message => "Oh noes!")
        Rails.logger.warning "Bad things, re: Member ID #{member.id}!"
    end
end

But other than the extra things that we do, now we have two methods, which both iterate through our group’s members and notify them. Seems to violate DRY a little bit. It’s not the end of the world, but it could be better.

Enter Ruby blocks. Instead, we could do something like this:

class Group < ActiveRecord::Base
    def notify_members
        members.each do |member|
            member.notify
            yield member if block_given?
        end
    end

    def notify_members_with_logging
        notify_members do |member|
            Alert.create(:member => member, :message => "Oh noes!")
            Rails.logger.warning "Bad things, re: Member ID #{member.id}!"
        end
    end
end

Now our second method simply uses the first method, but adds some extra logging into the mix. We can yield the member up to the block, which is necessary because in this (contrived) example, our Alert creation and our logger message both want to specifically call out the member for later reference.

Code blocks. Spend some time with them. They can make your life better.

Responding to :js in Rails

There is an underused feature in the way Rails allows you to write respond_to blocks in your controllers, I think: specifically, in that you can (if you like), tell your controller action to respond directly to JavaScript with more JavaScript. Not simply responding with JSON, though you could do that; I mean you can write complete AJAX-y workflows and let Rails do most or all of the heavy lifting for you.

Let’s assume we’re going to have an action that might be called from a regular link OR it might be called via an ajax request. So we’ll want

respond to do |format|
  format.html {}
  format.js {}
end

Now if we link to our action like:

= link_to "Do the thing!", the_thing_path, :remote => true

we’ll get an attribute in the resulting anchor tag that looks like data-remote='true', and Rails will handle clicking on that link as if it were an ajax request to whatever the target url is, which in this case, will go to our action. It will fall into the format.js block, and since there’s nothing there, will try to execute the_thing.js.haml (or erb or whatever).

// the_thing.js.haml

Let’s try something extremely simple just to see that it works.

Let’s make a new rails app and a controller.

> rails new floop
> cd floop
> rails g controller Foos
# config/routes.rb
resources :foos do
Collection do
  get :foo
  end
end
# app/controllers/foos_controller.rb
class FoosController < ApplicationController
  def foo
    @hello = "Dave"
    respond_to do |format|
      format.js {}
    end
  end
end
# index
= link_to "foo", foo_foos_path, :data-remote => true
# app/views/foos/foo.js.erb

alert("It's working, <%= @hello %>");

That’s a lot of files. Let’s talk about what’s going on.

For starters, if you try this, when you click the “foo” link on the index page, a js alert dialogue will appear. Not only that, but it says “It’s working, Dave.” It worked! But how?

In blatant disregard of rails convention, we created a custom route with our other actions for the foos controller. Having done that, we told that action (in the controller) it could respond to js. We created a js template in the views folder with the same name as our action, so it’s the template that rails tries to run. When we click the link, rails does run it, and because it’s an erb (or haml or slim) template, we can put Ruby in it, too. This is pretty awesome.

That’s really all there is to it. Using just this mechanism you could submit a form with data-remote => true and then save a record and have the resulting js template replace the form with a different partial.

I’m considering putting together a more extended, practical example of this type of technique. Is this interesting? (Y/N) Let me know.

Yoyo, so you can yo while you yo

yo2-638x358

Things I learned: Yo has an api

Yoyo is a gem1 for you to… call the Yo API. So. Well. That’s a thing you can do, now.

The API is pretty interesting, and (I guess) not surprisingly is very limited. You must setup an API account, which cannot be the same as your normal YO account. With your new API token, you can make POST requests to:

  • YO at some specific user.
  • mass YO to all your “subscribers” (anyone who has every YO’d your API account).

There doesn’t seem to be any way to ‘unsubscribe’ from a YO api account, other than you can (of course) block any given YO account from within the YO app.

Also, you can supply an endpoint to YO, which they will send a GET request to every time someone YOs your API account. In other words, if you want stats, the onus is upon you to set up an endpoint to keep track of exactly when and how many times other YO users have YO’d you.

That’s about it, I think.


  1. I’ve made a few gems in the past, but it’s been awhile. I referred to the quite excellent How I start by @steveklabnik. Recommended, if you, like me, were rusty on Ruby Gem assemblage. 

10 things I’ve learned about working with rails.

It seems to have become a little bit fashionable recently to hate on rails. I understand the criticisms, and many of them are completely valid points. But I still love rails.

Here’s some things that, over the last six years, I feel like I’ve learned about working with rails. YMMV.

  1. There is a huge benefit to the way that RESTful routes and controllers, AR models, and Rails view helpers work together. It’s great. If there is any one thing that helped make Rails successful, it is this. So much stuff just works, and you can get a significant amount of a web application going with just these things. Yes, it’s just CRUD. But it’s CRUD with a beautiful shell around it that works great. Learn it. Use it.

  2. polymorphic_path is great as long as you understand it. If you’re organizing your app in the way rails encourages you by convention, it works perfectly.

  3. Take the time to understand Ruby blocks, how methods accept blocks, and how yield works. Ruby uses it everywhere and so does rails, and if you don’t understand it, there are huge parts of rails that simply won’t make any clear sense to you. You’ll understand how to use it, but not why it works, or how to make code that works the same way. I try to revisit this periodically because I’m always forgetting some of the details. It’s worthwhile.

  4. Don’t put data content migrations into database migrations. Don’t do it. You will argue that it makes sense and is completely harmless in just this one case, and then later you will regret it. Stay away. There are dragons.

  5. Keep your migrations in a state such that you can clone the app afresh and run rake db:migrate any time. It should work. This is another reason not to have data content changes in a migration.

  6. If you aren’t going to maintain a db/seeds.rb file, it should be empty. Don’t let it sit in a broken state. Delete the code or fix it. This same should go for any other broken code, but I’ve seen it often in seeds.rb files.

  7. Be selective about which 3rd party gems you allow to manage big parts of your app. That’s great that you built your app with devise and cancan. What are you going to do in three years when you want to upgrade to the latest version of rails and maybe devise is no longer maintained? Not possible, you say. Yes it is; eventually, it’s almost certain that the cool gem of the week will no longer be maintained. I like devise well enough, too. But make sure you are okay with the prospect of eventually migrating to a different authentication gem, or maintaining a fork of devise on your own. It might never happen. Or it might. It probably will.

  8. Yes, do TDD. If you aren’t going to do TDD, then at least write tests. No, don’t bend your code into pretzels to make it “easy to test”, but if your code seems impossible to test, this indicates a problem. Something’s not right.

  9. If there’s more ruby code in your views than simply calling view helpers and form helpers or iterating through a collection, then there’s too much Ruby code in your views. Put it somewhere else. Maybe a controller or maybe a model or maybe a poro. But somewhere.

  10. Do learn to develop your own gems, particularly gems that your can use with rails. It is knowledge that will serve you well in understanding rails better, and in understanding gems better, for that eventual day when you need to maintain your own fork of devise that works with Rails 6.


Thoughts? I feel like each of these (well, most of them) could be expanded into its own post. Which one would you want to see?