Doesn't a DBI::Row respond to #to_h?  If not teach it and be sure to
add:

class Hash
  def to_h
    self
  end
end

You can define an attr method


module AttrDBI
  def attr_dbi( *args )
    @dbi_fields |= args
    attr_accessor( *args )
  end

  def dbi_fields
    @dbi_fields
  end
end

class Person
  extend AttrDBI

  attr_dbi :person_id,
    :last_name
    ...

  def initialize(row)
    row = row.to_h
    self.class.dbi_fields.each {|f| send("#{f}=", row[f] }
  end

T.