Skip to content

Instantly share code, notes, and snippets.

@ryandhaase
Last active August 2, 2018 18:09
Show Gist options
  • Select an option

  • Save ryandhaase/604e02fedf26e9d74043 to your computer and use it in GitHub Desktop.

Select an option

Save ryandhaase/604e02fedf26e9d74043 to your computer and use it in GitHub Desktop.
Mortgage Affordability Calculator - Built in Ruby on Rails

Mortgage Affordability Calculator - Built in Ruby on Rails

Functionality
  1. Send a GET request containing the following user inputs to Zillow's Mortgage Affordability API. Inputs as follows:
  • Annual Income, Monthly Payment, Down, Monthly Debts, Rate, Schedule, Term, Debt to Income, Income Tax, Property Tax, Hazard, PMI, HOA, ZIP
  1. A successful response from the GET request will contain the following attributes/information:
    • Affordability Amount, Monthly Principle and Interest, Monthly Property Tax, Monthly Hazard Insurance, Monthly PMI, Monthly HOA Dues, Total Monthly Payment, Total Payments, Total Interest Payments, Total Principal, Total Taxes Fees and Insurance, Monthly Income, Monthly Debts, Monthly Income Tax, Monthly Remaining Budget
Build:
  • Figaro is a useful gem making is possible to easily set environment variables and more importantly it allows you to keep private tokens/api keys from being tracked by GIT.
    • Include the gem Figaro in your Gemfile and run bundle in the terminal.
    • Once the gem is bundled, in the terminal run figaro install. This will create an application.yml file in your config directory - as well as create a .gitignore file.
  • To set personal API key as an environment variable:
    • In config/application/yml set:

      zillow_api_key: "YOUR API KEY"
      test:
        zillow_api_key: ~
    • You can call the zillow_api_key with ENV['zillow_api_key']. Put this where you would normally put the API key.

  • Install gem RestClient to handle HTTP requests to the Zillow Server.
  • Create a database-less model called Calculator which will contain the API method. I have searched through StackOverflow and come to the conclusion that there are a wide range of opinions as to whether or not to include the API call in a model or a library. In the end, I decided to go with a model since in this instance the web application is very small and I wasn't worried about code bloat.
    • Require the RestClient gem at the head of the model with require 'rest-client'. This will give us access to RestClient methods.
    • Below is a working API call. I have tested this call in the terminal using Calculator.mortage_affordability({ :annualincome => '100000', :monthlypayment => '1000', :down => '10000', :monthlydebts => '2000' }) and the response from the zillow server is a success.
      def self.mortage_affordability(options = {})
        options[:estimate] = 'false'
        options[:output] = 'json'
      
        base_uri = "http://www.zillow.com/webservice/mortgage/CalculateAffordability.htm?"
      
        api_key = 'zws-id=' + ENV['zillow_api_key'] + '&'
      
        unless options[:annualincome].present? || options[:monthlypayment].present?
          raise ArgumentError, 'Is required: either Annual Income or Monthly Payment!'
        end
      
        unless options[:down].present?
          raise ArgumentError, 'The Amount Down is required'
        end
      
        unless options[:monthlydebts].present?
          raise ArgumentError, 'The Monthly Debts option is required'
        end
      
        response = RestClient.get base_uri + api_key + options.map { |k, v| "#{k}=#{v}" }.join('&')
      
        response_hash = JSON.parse(response)
      end
    • In the method above I have done the following:
    • I have an options hash: options = {}. I'm expecting up to 14 to be included in the API call.
    • I have set options[:estimate] and options[:output] directly in the method. At this time I do not want to give the user the option of whether or not they want an estimate. Additionally, I want the request to return JSON which is why I specified it here.
    • I declared a variable called base_uri. This makes it easier further down the method to concatenate the full URL for the request.
    • I declared a varibale called api_key which concatenates together my api token/key with Zillow's unique naming structure.
    • I have declared 3 unless statements which check whether or not the user has input the minimum requirments/values as specified by the Zillow API guide.
    • I declare and send a RestClient.get request which concatenates the base-uri, api_key, and all the hash options. This has been assigned to the response variable.
    • Lastly, I parse the response and assign it to response_hash so that later the attributes can be accessed via response_hash['response']['monthlyIncomeTax']
    • Within config/routes.rb define the index route and set it to the root page. This will make the index view the homepage/default:
        get 'calculator/index'
        root to: 'calculator#index'
    • Create a controller called Calculator with index and get_rates actions. The index action is only needed to display the index view. The get_rates action will act as the middle man in passing the form attributes to the mortgage_affordability method.
      • Pseudo code:

        get_rates
          assign the form parameters to a variable
          call Calculator.mortgage_affordability passign in the paramters
          listen for a response
          if response is a success save response to a variable
          if response fails render error to view
          respond to format html and js
        end
        
    • Create an index.html.erb view.
    • Create a form partial for _get_rates.html.erb and display the partial in the index view using <%= render partial: 'get_rates' %>.
    • Within the form partial, create a form using form_for. This form will have a handful of text_fields which will be optional inputs for the user. The possible inputs are detailed in the functionality section.
      • The form code will look like this:

        <%= form_for :get_rates do |f| %>
          <%= f.text_field :annualincome %>
          <%= f.text_field :monthlypayment %>
          <%= f.text_field :down %>
          <%= f.text_field :monthlydebts %>
          # ... there ~ 14 options/attributes
          <%= f.submit %>
        <% end %>
        
    • Create another view called get_rates.js.erb. This is where we will use jQuery to append the API response to get_rates.html.erb.
      • Pseudo code:

        if the get_rates call was a success
          append the response to html element within get_rates view
        else
          render error
        end
        
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment