A lot of people have left the church. I’ve entertained the idea many times myself. But I never really thought the church would leave me.

Today, the United Methodist Church, in which I was baptized, grew up, ordained, and for many years served as one of its clergy, voted to essentially split over the “issue” of homosexuality.

A lot of details remain to be clarified. But the ultimate destiny is now clear. The United Methodist Church will collectively stick it’s head in the sand and declare that homosexuals have no place in their club. Those of us who envision a church defined by more than it’s narrow understanding of human sexuality and who wish for the church to welcome everyone, regardless of anything, will be left to create a new church born from the broken remains.

Among reasons for churches to split, this must rank among the most petty.

This is the message the United Methodist Church has for gay and lesbian people: you are not acceptable. You do not belong. You are not welcome. Think about that. That’s the good news from the UMC. What future is there in that? Do conservatives honestly think that they will march gleefully into righteousness by excluding and condemning a marginalized group in our society that has only recently started to find their place in our culture? Is that the basis of our church? It is so critical that we express this cruel and exclusionary position, rooted in homophobia, that our church can split in half.

The plan that has passed is called the Traditional Plan. How appropriate. What church thinks it’s future lies in clinging to tradition?

Sadly, this move will do little to address the underlying problems facing the UMC. Those who think clarifying the church’s position on homosexuality will lead to a new era of growth are not only out of touch with reality, they also don’t understand the fundamental problems of the UMC. Like our structure. Like the itinerancy. Like our property laden congregations. Like the lack of viability of many of our churches. Like the guaranteed appointment. This is not a plan to address any of the problems facing the church. This is a plan to satisfy a self-righteous agenda attempting to preserve some self-perceived holiness in a misguided attempt to enforce sexual norms that literally have nothing to do with the gospel of Jesus Christ.

I am saddened by this news. But like all bad news, there is also some hope. Perhaps this moment will empower the emergence of a new kind of church, that will address the long-standing issues facing the UMC and at the same time offer some good news for all of God’s people.

In the meantime, I feel churhcless.

A job, however frustrating, is made more pleasurable when it is situated in a context that connects to one's passion.

A Dream Job

There is no such thing as a perfect job.

All jobs have their ups and downs. As I begin a job search, I’m really not thinking so much about the actual job as I am about the community and culture of the company for which I will work. The job will have it’s pros and cons, like all jobs. Hopefully more pros than cons, obviously. But the environment in which I work will really shape my happiness and enjoyment, as well as my effectivenss.

That’s because a job - however frustrating - is made more pleasurable when it is situated in a context that connects to one’s passion. If I find myself reformating huge XML files for some application, the task would be bearable if the mission and culture of the organization inspires my passions.

To that end, I am hoping to find the following things in my next place of employment:

I’m sure there are other things that matter to me - like compensation, benefits, etc. But the above list captures the things that come to my mind as distinctives. I hope I can find a rewarding work place, that empowers my Vermont lifestly, and engages the world with positive change all while leveraging my unique set of talents.

How hard can that be to find?

I think I went off the rails!

My First Rails Project

For my first Ruby on Rails project, I chose to build an app I called: Chamption: A Playbook Manager for Football Coaches. Champion allows a football coach to create a collection of playbooks, add plays to them, create opponents and schedule games against their opponents.

The project turned out to be larger than I expected. Initially, I thought I would just do the “playbook” portion, but as I went along and thought things through, I added the “games” piece and then things just kept expanding. In church, we would call this ‘mission creep.’ So, I had to reign myself in and focus on the core requirements from Flatiron.

Here is a video of the app that introduces the core concepts:

To exemplify some of the code, let’s look at how you create a user and also add a profile for that user. The user is a coach, and when they create an account, they can add some additional details that are stored in a separate table. If they choose to log in with Facebook, an empty profile is created for them. First, let’s look at how the models are configured:

class User < ApplicationRecord

  has_one :profile, dependent: :destroy
  has_many :playbooks
  has_many :plays, -> { distinct }, through: :playbooks 
  has_many :games
  has_many :opponents, through: :games

  validates :name, presence: true
  validates :name, length: { minimum: 2 }
  validates :email, presence: true
  validates :email, uniqueness: true
  validates_format_of :email,:with => /\A[^@\s]+@([^@\s]+\.)+[^@\s]+\z/

  accepts_nested_attributes_for :profile

You will notice that the user model uses has_secure_password in order to use bcrypt to encrypt the password. If the user comes from Facebook, a dummy password is supplied just to make sure it passes the validations. Also, you will notice that a number of other validations are set up to ensure the user name is of a certain length and the email is valid and unique. The email address serves as the user’s identity. Finally, notice that a user has one profile and can accept nested attribues for profiles.

Now, let’s look at the profile model:

class Profile < ApplicationRecord
  belongs_to :user

This one is super simple. It simply belongs to a user. This, along with the relationship set up in the user model, sets up the one to one relaionship with a user, so that a user has one and only one profile.

Most of the work of creating a new user is handled in the user controller, so let’s look at that:

class UsersController < ApplicationController
  before_action :require_login
  skip_before_action :require_login, only: [:new, :create]

  def new
    @user =
    @user.profile =

  def create
    @user =, :email, :nickname, :password, profile_attributes: [:role, :nickname]))
      session[:user_id] =
      redirect_to @user
      render 'new'

  def show
    if params[:id].to_i == 
      @user = current_user 
      redirect_to current_user 

  def edit
    @user = User.find(params[:id])

  def update 
    @user = User.find_by(id: params[:id])
    @user.update(user_params(:name, :email, :nickname, profile_attributes: [:role, :nickname]))
    redirect_to user_path @user 

  def index
    @users = User.all


  def user_params(*args)

  def require_login
    return head(:forbidden) unless logged_in?

In this code, you are required to be logged in for all the routes except for the new and create routes. These are the ones of interest here. You don’t need to be logged in for those, becuase you are creating a new account, hence can’t be logged in, right? If you look at the create method, if creates a new user based on the input the user provided, and if the user can be saved, it then logs that user in and displays the user’s show page, which is their profile page. If the user can’t be saved, that means one of the validations didn’t pass, so the create form is shown again with errors displayed.

To see how the errors are handled, let’s look at the new user form:

<div class='row justify-content-center'>
  <div class='col-5'>
    <h1 class='display-22'>Sign Up</h1>

    <%= render partial: 'shared/error_messages', locals: { item: @user } %>
    <%= render partial: 'form', locals: { submit_msg: 'Create Coach' } %>

    <p>Already have an account? <%= link_to "Log in here.", login_path %></p>
    <p><%= link_to('Or log in with Facebook!', '/auth/facebook') %></p>


Here I made use of partials. The first partial is used across all forms to show errors. It is stored in the shared folder and passed the object that has errors as a local variable. This allows the error partial to be generic. Here it is:

<% if item.errors.any? %>
  <div id="error_explanation">
    <div class="alert alert-danger">
      <p>The form contains <%= pluralize(item.errors.count, "error") %>.</p>
    <% item.errors.full_messages.each do |msg| %>
      <li><%= msg %></li>
    <% end %>
<% end %>

Finally, let me show you the partial for the new user form itself. It uses a local variable to customize the text on the submit button:

<%= form_for @user do |f| %>
  <div class="form-group">
    <%= f.label 'Name' %>
    <%= f.text_field :name, class: 'form-control' %>
  <div class='form-group'>
    <%= f.label 'Email' %>
    <%= f.text_field :email, class: 'form-control' %>
  <%= f.fields_for :profile do |ff| %>
    <div class='form-group'>
      <%= ff.label 'Nickname' %>
      <%= ff.text_field :nickname, class: 'form-control' %>
    <div class='form-group'>
      <%= ff.label 'Role' %>
      <%= ff.text_field :role, class: 'form-control' %>
  <% end %>
  <div class="form-group">
    <%= f.label 'Password' %>
    <%= f.password_field :password, class: 'form-control' %>
  <%= f.submit submit_msg, class: 'btn btn-primary' %>
<% end %>

This project was challenging for me - and I learned a lot. I started off trying to use bootstrap which turned out to be a daunting learning experience in and of itself. And then the general scope of my project expanded, and I had to learn a lot more stuff. I must say I like learning new things…but I also like getting something done. At times, these interests were in conflict. I reminded myself of one of Steve Job’s famous qoutes: “Real artists ship.” So, now, I’m done!

Sinatra is classy.

My First Sinatra Project

Slowly, but surely, I am working my way through the Flatiron School’s curriculum. Though it is taking me a bit longer than I expected, I also have relocated to Vermont, sold a house, and settled into my new home. So, I guess I shouldn’t be too hard on myself. Living in Vermont is great and I’m hopeful that I can refocus now on getting my Flatiron work done.

To that end, I have completed my first Sinatra application. Sinatara is a framework for web apps that, along with ActiveRecord, can generate some pretty powerful CRUD based apps. Sinatra provides ‘routes’, which are basically pathways to content that your app will follow in response to HTTP requests. These routes allow for loading and manipulating data through Ruby methods.

For my Sinatra app, I imagined a survey system that would allow users to both create and take surveys. I made some decisions along the way to limit the scope of what I would create for this project. These limitations were selected so that I could fulfill the requirements of the Flatiron curriculum, but also get the project done without going crazy. I’m still going crazy anyway.

To begin, I though about my database and the relationships between the data. I came up with a model that looks something like this:

Sinatra Project Database Model

The “responses” model was not copmleted as previously indicated. So, there are four databases that I used:

So, with that basic model in mind, I got to building the CRUD functionality, models, routes, etc.

To illustrate some of what I learned, let me go over the user authentication and login procedures:

class SessionController < ApplicationController 
  get '/login' do
    if !logged_in? 
      erb :'sessions/login'
      @user = User.find_by(email: session[:email])
      redirect :'/'

  get '/registration' do
    if !logged_in?
      erb :'sessions/registration'
      @user = User.find_by(email: session[:email])
      redirect :'/'

  post '/registration' do
     @user = params[:username], firstname: params[:firstname], lastname: params[:lastname], password: params[:password], email: params[:email])
     if !logged_in? && @user.valid?
      session[:email] = params[:email]
      @my_surveys = @user.surveys
      @all_surveys = Survey.all
      redirect '/surveys'
      flash[:message] = ""
      @user.errors.messages.each do |key, message|
        message.each do |text|
        flash[:message] += text + "<br />"
      redirect :'/'

  post '/sessions' do
    login(params[:email], params[:password])
    @user = current_user
    @my_surveys = @user.surveys
    @all_surveys = Survey.all
    redirect '/surveys' 

  get '/logout' do
    redirect :'/'


The SessionController manages the user login experience. But three helpers I created in ApplicationController are also relevant:

  helpers do 

    def logged_in?

    def login(email, password)
      user = User.find_by(email: email)
      if user && user.authenticate(password)
       session[:email] =
       session[:user_name] = user.firstname + ' ' + user.lastname
       redirect '/login'

    def current_user
      if logged_in?
        User.find_by(email: session[:email])
        redirect '/' 

These helper methods assist the login process by providing the following funtionality:

Now, looking back at SessionController, there are four Sinatra routes that manage the login process:

get ‘/login’ do: This route checks to see if a user is logged in already. If not, it renders the login form. If they are logged in, the user is redirected to their home page.

get ‘/registration’ do: This route renders the registration form if the user is not logged in already.

post ‘/registration’ do: This route handles the registration process. This is where I used validation and flash messages to provide feedback to the user. The validation flash settings are configured in the User class:

class User < ActiveRecord::Base

  validates :username, presence: { message: "You must provide a username." }, uniqueness: { message: "Username is already taken." }
  validates :email, presence: { message: "You must provide an email." }, uniqueness: { message: "That email is alreday taken." } 
  validates :password, presence: { message: "Password cannot be blank." }
  has_secure_password validations: false

  has_many :surveys


post ‘/sessions’ do: Here, this route logs the user in and then send them to the ‘/surveys’ route where their surveys will be listed for editing, creating, etc.

get ‘/logtout’ do: Finally, this route clears the session hash, logging the user out.

Ok. This post is long and fairly boring, so I’m going to stop here. The CRUD aspect of this app will have to wait for another blog post. That stuff is handled by the SurveyController class. Fun!

Ruby is a precious gem.

Making A CLI in Ruby

For my educational benefit and as part of the process at the Flatiron School, I recently wrote a CLI gem in Ruby. This was a great learning experience and a bit of challenge for a newbie like myself. That said, it was also rewarding and I have gained a much better understanding of things Ruby. Mission accomplished.

My idea was simple, since this was my first effort. So, I decided to make a CLI that searches for a list of doctors in a particular zipcode and then allow the user to get more details about a particular doctor. I cleverly named this app “doctor_finder.” Why? Because it finds doctors!

At first, I thought I would use one of the large, well-known sites, like WebMD or HealthGrades. I also looked at insurance companies websites and government websites. All of them posed challenges that I could not overcome. The commercial sites blocked scrapers, and I wasn’t savvy enough to get around their blocks. Other sites required the user to fill out forms that I could not easily get past in an automated way.

I finally settled on Zocdoc. This website met my needs and allowed me to search for a doctor by zipcode by using a customized URL. It returned 20 doctors to me, that I could parse with Nokogiri.

But first things first. The first step in this whole process was setting up properly for a Ruby Gem. This process is made simple thanks to Bundler. Bundler includes a gem command that creates the directories and basic files you need to get started. It also includes some automation in your gemspec file so you don’t have to manually maintain your list of files. Finally, it sets up a git repo for you. Basically it gets you off to a good start:

bundler gem doctor_finder

Bundler will even ask you if you want to include a license and a code of conduct. The basic structure of a gem includes a bin directory for storing executable files, a lib directory for storing the main code, modules and classes, etc, and a spec or test directory for your testing tools. I didn’t use any tests for this project, but I’m sure I will in the future.

With that done, the next step is to figure out how you will set up your dependencies and files to get things working. Since I was building a CLI, it made sense to start there. I decided that my CLI would call a CLI object and run a method on that object - and that that CLI object would take care of things from then on. So, to get that going, I needed to create a file in the bin directory called ‘doctor_finder.rb’ which would serve as my main executable file. So I also needed to chmod +x doctor_finder.rb to make it executable. Then, I added this code to the new file:

#!/usr/bin/env ruby
require_relative "../lib/doctor_finder"

So, the key line is the First, I assume a moduel (namespace) called “DoctorFinder” that is actually created by bundler in the versions file. Then I assume an object called CLI, I create a new one, and I call the method call.

So I need to create the CLI class and include a method called call. I’m pasting in the completed object below. This file would be found in the doctor_finder/lib/doctor_finder directory.

# CLI Main file defining the CLI class

class DoctorFinder::CLI

  def call 
    puts "\nWelcome to Hooper's Doctor Finder."
    puts "\nWith HDF you can retrieve a list of doctors by zipcode and then get more details about a particular doctor on that list. It's easy!"

  def get_zipcode
    # Gets a valid zip code from the user
    zip = "" 
    while !iszipcode?(zip)
      puts "\nPlease enter a valid zipcode:"
      zip = gets.chomp[0..4]

  def iszipcode?(zipcode)
    # Provides a basic level of validation for user input of zipcode.
    if zipcode.length == 5 && zipcode.scan(/\D/).empty?

  def show_list(zipcode)
    # Calls scraper and prints a list of doctors based on the zip code entered by the user.
    docs = DoctorFinder::Scraper.scrape_by_zipcode(zipcode)
    docs.each.with_index(1) do |doc, i|
      puts "#{i}. #{} - #{doc.speciality} - #{}, #{doc.state} #{}"

  def get_choice_from_list
    # Gets a valid choice from the list of Doctors.

    choice = nil 

    while choice != "exit" && choice != "q"
      puts "\n[1..#{DoctorFinder::Doctor.all.length}] Select Doctor | [zip] Start over with new zipcode | [exit] To quit"
      choice = gets.chomp
      if choice.to_i > 0 && choice.to_i < DoctorFinder::Doctor.all.length+1
        doc = DoctorFinder::Scraper.scrape_for_details(DoctorFinder::Doctor.all[choice.to_i-1]) 
        puts "======================================\n"
        puts doc.street
        puts + ', ' + doc.state + ' ' +
        puts "--------------------------------------\n"
        puts "Areas of Specialty:"
        puts doc.areas
        puts doc.details
      elsif choice == "zip"

  def farewell
    # Tells the user goodbye.
    puts "\n\nThank you for using Hooper's Doctor Finder.  This was an educational experiment, and I learned a lot.  At first it seemed hard, but then it got easier.\n\nSee you next time.\n\n\n\n"

Let me explain the purpose each method:

call: This is the initial method that is called from the executbable itself. All it does is print some introductory content and then call other methods. First I want to get a list of doctors based on a zipcode the user enters. So, I call a function list_doctors and I pass it get_zipcode. After that, I want to run the main menu loop, and then, when the user is done, say farewell.

get_zipcode: This method simply asks the user for a zipcode and then returns that zipcode.

iszipcode?: This method runs some very basic validation on the user input. The good news is that Zocdoc is very tolerant of user input - so even if they don’t enter a proper zipcode Zocdoc will do its best to return a list of doctors to us.

list_doctors: Prints out a list of doctors based on a zipcode passed to it. In order to accopmlish this, it makes calls to two other classes, Scraper and Doctor. I’ll show you those below.

get_choice_from_list: This is my poorly named main menu loop. Until the user enters valid input, it shows a list of doctors, pulled from the Doctor object. If they choose a valid doctor, it prints that doctors details.

farewell: Says goodbye when the user exits.

Next, lets take a look at the Doctor object. All this class does is store data for a doctor and it maintains an array of all the doctors:

# The Doctor class

class DoctorFinder::Doctor

attr_accessor :name, :url, :speciality, :street, :city, :state, :zip, :details, :areas

  @@all = []

  def initialize
    @@all << self

  def self.all

  def self.clear
    @@all = []

Not much going on here. But if this was part of a larger application, having the Doctor class as a separate class might prove useful. One thing to note - I made a clear method to empty out the array of doctors so I could do a new search in a new zipcode without creating another instance. For the rest of the app, the action is in the Scraper class:

# The Scraper class

class DoctorFinder::Scraper

  BASE_URL = ""

  def self.scrape_by_zipcode(zipcode)
    html = Nokogiri::HTML(open("#{BASE_URL}search?address=#{zipcode}&insurance_carrier=-1&day_filter=AnyDay&gender=-1&language=-1&offset=0&insurance_plan=-1&reason_visit=75&after_5pm=false&before_10am=false&sees_children=false&sort_type=Default&dr_specialty=153&"))
    slice = html.css('.js-prof-row-container')
    slice.each do |doctor| # will go through the HTML and create new doctor instances
      doc = = doctor.css('.js-profile-link').text.strip.gsub("\n", ' ').squeeze(' ')
      doc.speciality = doctor.css('.ch-prof-row-speciality').text.strip
      doc.url = BASE_URL + doctor.css('.js-profile-link')[0]['href']
      address = doctor.css('.js-search-prof-row-address').text.strip
      doc.street = address.slice(/^\d+[ ][\w+[ ]]+/) # To format the text correctly, had to use some regex = address[/[ ][ ]+[\w+[.]*[ ]]*[,]/].strip.chop
      doc.state = address[/[A-Z][A-Z]/] = address[/\d{5}/] 

  def self.scrape_for_details(doctor)
    html = Nokogiri::HTML(open(doctor.url))
    doctor.details = html.css('.profile-professional-statement').text.squeeze(' ')
    if doctor.details.strip == ""
      doctor.details = "No further details were available."
    doctor.areas = html.css('li.specialty').text.squeeze(" ").gsub("\r\n \r\n ", "\r\n").lstrip

The Scraper class has two methods and one constant. The BASE_URL constant was just a helpful way to desingate the web site I was scraping. The other methods:

scrape_by_zipcode(zipcode) takes a zipcode and scapes Zocdocs for a list of doctors based on that zipcode. I encode the zipcode in a search string nad usethat from my open-uri request. I slice a chunk of html out of the whole site to narrow in on just the doctor info. Then I iterate through the array from Nokogiri tossing the data I want into a new Doctor instance. I use a number of regular expressions and string methods to get only the data I want in the object. I return the array of all the doctors.

scrape_for_details(doctor) takes a doctor and fills in more data about that doctor by scraping the doctor’s detial page. I use the url I scraped before when I constructed the doctor list and pull down the details. Then, like before, I use text methods and regular expressions to get the data I want in the right place. I return the doctor, but now with more details.

So, that’s basically how this things works. As I said at the begninng, I learned a lot playing with this. Now, onward!