[Skip To Content]


i just want to be me / when i can, i will / try to understand / that when i can, i will

“Mayonaise”, Smashing Pumpkins

# dont_fucking_repeat_yourself

  1. table :user, options => "TYPE=InnoDB" do |t|
  2. # Adds has_many :tasks to the model, and adds an index on the target column
  3. # in the associated table (tasks.user_id, in this case.)
  4. t.has_many :tasks
  5. # Create a VARCHAR(50) NOT NULL column, validates_length_of :login,
  6. # :in => 5..50, validates_presence_of :login, validates_uniqueness_of
  7. # :login and a unique index for the column.
  8. t.string :login, :limit => 5..50, :null => false, :unique => true
  9. # Create a VARCHAR(40) NOT NULL column ready for a SHA1 hash of the
  10. # :password field. Also adds validates_confirmation_of :password, and an
  11. # accessor for :password_confirmation. (:confirmation isn't limited to
  12. # passwords, although it's the main use of it.)
  13. t.hash :password, :limit => 4..16, :null => false, :confirmation => true
  14. # Create a DATETIME NOT NULL column for created_at
  15. t.created_at
  16. end
  17. table :task, :options => "TYPE=InnoDB" do |t|
  18. # Adds belongs_to :user, :allow_nil => true to the model. Also adds an
  19. # user_id INTEGER column, and creates an index for it.
  20. t.belongs_to :user, :allow_nil => true
  21. # Adds a VARCHAR(128) NOT NULL column, validates_length_of :title, :in
  22. # => 1..128, validates_presence_of :title, and an index for the column.
  23. t.string :title, :limit => 1..128, :null => false, :index => true
  24. # Adds a DATETIME column, no validation.
  25. t.datetime :due
  26. # Adds a BOOLEAN NOT NULL DEFAULT FALSE column. Doesn't add a
  27. # validates_presence_of validation.
  28. t.boolean :done, :default => false, :null => false
  29. # Create DATETIME NOT NULL columns for created_at and updated_at
  30. t.timestamps
  31. # Create a unique index for the two columns due and done.
  32. t.index :due, :done, :unique => true
  33. # Create an index for the two columns user_id and title.
  34. t.index :user_id, :title
  35. end

So, you’re a Rails developer? CHECK! You have this great idea for a new application, the one which will surely get Yahoo and Google involved in a bidding war? CHECK! But you don’t actually start developing it because you are fed up having to run script/generate model model_name, editing the migration for the table, writing the tests for all the rules which are implied by the database (Such as maximum lengths for columns and column uniqueness), and then editing the model to pass those tests? CHECK!

To solve this problem, you can see the proposed syntax for my (tentatively titled) dont_fucking_repeat_yourself plugin. After creating a file much in the manner of that above, you simply run the (tentatively titled) i_am_bored_of_repeating_myself rake task and all your models, migrations and tests are generated.

It will also allow you to add new models during development, so no longer will you think “No, I won’t add that feature because it requires a new table and I can’t be arsed doing the create-model-write-migration-write-tests-edit-model dance.”

Obviously this only helps with the initial creation of models and doesn’t attempt to help you when you want to change your title column to hold more than 128 characters, but man, it should really speed up those early days of development.

If anyone has any comments let me know, a link to my email is at the bottom of this page. Hell, if anyone reads this at all, it’ll be good to hear from you.

(And if anyone is offended by the swearing, I’m sorry, but DHH started it.)

Wikipedian Protester

I must resist the temptation to simply mirror xkcd.