Permalink
Browse files

interface-first-hobo-style

## Interface first Hobo style

The next thing we're going to do is sketch out our models. If you're a fully signed up devotee of the Rails Way, that should ring a few alarm bells. What happened to [interface first](http://gettingreal.37signals.com/ch09_Interface_First.php)? We do believe in Interface First. Absolutely. But for Hobos, interface first means first priority, not first task.

The reason is, we think we've rewritten this rule:

> Design is relatively light. A paper sketch is cheap and easy to change. html designs are still relatively simple to modify (or throw out). That's not true of programming. Designing first keeps you flexible. Programming first fences you in and sets you up for additional costs.

In our experience, experimenting with an app by actually building a prototype with Hobo, is actually quicker than creating html designs. How's that for getting real? We could waffle for a good while on this point, but that's probably best saved for a blog post. For now let's dive in and get this app running.


# The models

Let's review what we want this app to do:

 * Track multiple projects
 * Each having a collection of stories
 * Stories are just a brief chunk of text
 * A story can be assigned a current status and a set of outstanding tasks
 * Tasks can be assigned to users
 * Users can get an easy heads up of the tasks they are assigned to

Sounds to me like we just sketched a first-cut of our models. We'll start with:

 * `Project` (with a name)
	has many stories
 * `Story` (with a title, description and status)
	belongs to a project
	has many tasks
 * `Task` (with a description)
	belongs to a story
	has many users (through task-assignments)
 * `User` (we'll stick with the standard fields provided by Hobo)
	has many tasks (through task-assignments)

Hopefully the connection between the goal and those models is clear. If not, you'll probably find it gets easier once you've done it a few times. Before long you'll be throwing models into your app without even stopping to write the names down. Of course -- chances are you've got something wrong, made a bad decision. So? Just throw them away and create some new ones when the time comes. We're sketching here!

Here's how we create these with a Hobo generator:

	$ hobo generate resource project name:string
	$ hobo generate resource story   title:string body:text status:string
	$ hobo generate resource task    description:string

Task assignments are just a back-end model. They don't need a controller, so:

	$ hobo generate model task_assignment
  • Loading branch information...
iox committed Jun 3, 2013
1 parent 6c148d3 commit a91632278ffa6b62de5ba3fa5717f95ee3aa3171
@@ -0,0 +1,7 @@
class ProjectsController < ApplicationController
hobo_model_controller
auto_actions :all
end
@@ -0,0 +1,7 @@
class StoriesController < ApplicationController
hobo_model_controller
auto_actions :all
end
@@ -0,0 +1,7 @@
class TasksController < ApplicationController
hobo_model_controller
auto_actions :all
end
View
@@ -0,0 +1,29 @@
class Project < ActiveRecord::Base
hobo_model # Don't put anything above this
fields do
name :string
timestamps
end
attr_accessible :name
# --- Permissions --- #
def create_permitted?
acting_user.administrator?
end
def update_permitted?
acting_user.administrator?
end
def destroy_permitted?
acting_user.administrator?
end
def view_permitted?(field)
true
end
end
View
@@ -0,0 +1,31 @@
class Story < ActiveRecord::Base
hobo_model # Don't put anything above this
fields do
title :string
body :text
status :string
timestamps
end
attr_accessible :title, :body, :status
# --- Permissions --- #
def create_permitted?
acting_user.administrator?
end
def update_permitted?
acting_user.administrator?
end
def destroy_permitted?
acting_user.administrator?
end
def view_permitted?(field)
true
end
end
View
@@ -0,0 +1,29 @@
class Task < ActiveRecord::Base
hobo_model # Don't put anything above this
fields do
description :string
timestamps
end
attr_accessible :description
# --- Permissions --- #
def create_permitted?
acting_user.administrator?
end
def update_permitted?
acting_user.administrator?
end
def destroy_permitted?
acting_user.administrator?
end
def view_permitted?(field)
true
end
end
@@ -0,0 +1,28 @@
class TaskAssignment < ActiveRecord::Base
hobo_model # Don't put anything above this
fields do
timestamps
end
attr_accessible
# --- Permissions --- #
def create_permitted?
acting_user.administrator?
end
def update_permitted?
acting_user.administrator?
end
def destroy_permitted?
acting_user.administrator?
end
def view_permitted?(field)
true
end
end
View
@@ -0,0 +1,11 @@
# Read about fixtures at http://api.rubyonrails.org/classes/ActiveRecord/Fixtures.html
# This model initially had no columns defined. If you add columns to the
# model remove the '{}' from the fixture names and add the columns immediately
# below each fixture, per the syntax in the comments below
#
one: {}
# column: value
#
two: {}
# column: value
View
@@ -0,0 +1,11 @@
# Read about fixtures at http://api.rubyonrails.org/classes/ActiveRecord/Fixtures.html
# This model initially had no columns defined. If you add columns to the
# model remove the '{}' from the fixture names and add the columns immediately
# below each fixture, per the syntax in the comments below
#
one: {}
# column: value
#
two: {}
# column: value
@@ -0,0 +1,11 @@
# Read about fixtures at http://api.rubyonrails.org/classes/ActiveRecord/Fixtures.html
# This model initially had no columns defined. If you add columns to the
# model remove the '{}' from the fixture names and add the columns immediately
# below each fixture, per the syntax in the comments below
#
one: {}
# column: value
#
two: {}
# column: value
View
@@ -0,0 +1,11 @@
# Read about fixtures at http://api.rubyonrails.org/classes/ActiveRecord/Fixtures.html
# This model initially had no columns defined. If you add columns to the
# model remove the '{}' from the fixture names and add the columns immediately
# below each fixture, per the syntax in the comments below
#
one: {}
# column: value
#
two: {}
# column: value
@@ -0,0 +1,7 @@
require 'test_helper'
class ProjectsControllerTest < ActionController::TestCase
# test "the truth" do
# assert true
# end
end
@@ -0,0 +1,7 @@
require 'test_helper'
class StoriesControllerTest < ActionController::TestCase
# test "the truth" do
# assert true
# end
end
@@ -0,0 +1,7 @@
require 'test_helper'
class TasksControllerTest < ActionController::TestCase
# test "the truth" do
# assert true
# end
end
@@ -0,0 +1,7 @@
require 'test_helper'
class ProjectTest < ActiveSupport::TestCase
# test "the truth" do
# assert true
# end
end
View
@@ -0,0 +1,7 @@
require 'test_helper'
class StoryTest < ActiveSupport::TestCase
# test "the truth" do
# assert true
# end
end
@@ -0,0 +1,7 @@
require 'test_helper'
class TaskAssignmentTest < ActiveSupport::TestCase
# test "the truth" do
# assert true
# end
end
View
@@ -0,0 +1,7 @@
require 'test_helper'
class TaskTest < ActiveSupport::TestCase
# test "the truth" do
# assert true
# end
end

0 comments on commit a916322

Please sign in to comment.