<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>ROFISH.net</title>
	<atom:link href="http://rofish.net/feed/" rel="self" type="application/rss+xml" />
	<link>http://rofish.net</link>
	<description>thoughts.collect{&#124;idea&#124; Blog.post idea}</description>
	<lastBuildDate>Sun, 08 Apr 2018 19:24:33 +0000</lastBuildDate>
	<language>en-US</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>https://wordpress.org/?v=4.4.17</generator>
	<item>
		<title>Ruby for Programmers – Part 17: On The ActiveRecord</title>
		<link>http://rofish.net/2014/02/ruby-for-programmers-part-17-on-the-activerecord/</link>
		<pubDate>Mon, 10 Feb 2014 05:15:37 +0000</pubDate>
		<dc:creator><![CDATA[Ryan Alyea]]></dc:creator>
				<category><![CDATA[Ruby For Programmers]]></category>

		<guid isPermaLink="false">http://rofish.net/?p=154</guid>
		<description><![CDATA[This goes a little into how to run SQL. You don&#8217;t need to know everything, but this is a great tutorial on straight SQL. Good news though, you don&#8217;t have to touch any SQL for this. Here&#8217;s the tl;dr: A &#8230; <a href="http://rofish.net/2014/02/ruby-for-programmers-part-17-on-the-activerecord/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
				<content:encoded><![CDATA[<p>This goes a little into how to run SQL. You don&#8217;t need to know everything, but <a href="http://www.postgresqltutorial.com/postgresql-select/">this is a great tutorial on straight SQL</a>. Good news though, you don&#8217;t have to touch any SQL for this. Here&#8217;s the tl;dr:</p>
<ul>
<li>A SQL table is a lot like a spreadsheet. You have rows and columns. You should have a table for each data model.</li>
<li>Tables and their columns need to manually created and removed. When you need to make a new column, you need to manually tell the system that it needs to be created.</li>
<li>&#8220;Primary&#8221; column(s) are unique and define it. Generally speaking this is just an id number. Rails sets it up so that the database will auto increment the id so you don&#8217;t have to worry.</li>
</ul>
<p>So let&#8217;s setup our database. We&#8217;ll be using Postgres, so we need to install it. For Macs, <a href="http://postgresapp.com">use Postgres.app</a>. It&#8217;s simple and easy. <a href="http://www.postgresql.org/download/windows/">Postgres provides an installer for Windows</a>. And Linux can use your favorite package manager.</p>
<p>And once it&#8217;s setup, we need a database (set of tables) to put it into. You can use the included GUI or the command &#8220;createdb&#8221; to create a database.</p>
<p>Then we need to install the pg gem, which might be a small issue on any machine. For example on Mac you may need to run <code>env ARCHFLAGS="-arch x86_64" gem install pg -- --with-pg-config=/Applications/Postgres.app/Contents/MacOS/bin/pg_config</code> to give it the right config file to build the C extension against. Googling eventually finds the right answer.</p>
<p>Hopefully now you have the gem installed, and we can run bundler with pg and ActiveRecord:</p>
<p></p><pre class="crayon-plain-tag">ruby '2.1.0'
source 'https://rubygems.org'
gem 'rack', '~&gt;1.5.2'
gem 'actionpack', '~&gt; 4.1.0.beta1'
gem 'actionview', '~&gt; 4.1.0.beta1'
gem 'railties', '~&gt; 4.1.0.beta1'
gem 'activerecord', '~&gt; 4.1.0.beta1'
gem 'pg'</pre><p> </p>
<p>And the Railtie:</p>
<p></p><pre class="crayon-plain-tag">require File.expand_path('../boot', __FILE__)

require 'rails'
require 'action_controller/railtie'
require 'action_view/railtie'
require 'active_record/railtie'

Bundler.require

module GenericCMS
  class Application &lt; Rails::Application
    # you could put some custom stuff here if you wanted

    config.secret_key_base = "rails really wants this to be defined"
  end
end</pre><p> </p>
<p>Now we need to setup the postgres password. Create a new file, config/database.yml, to put the postgres password that you used to setup the postgres root password:</p>
<p></p><pre class="crayon-plain-tag"># SQLite version 3.x
#   gem install sqlite3
#
#   Ensure the SQLite 3 gem is defined in your Gemfile
#   gem 'sqlite3'
development:
  adapter: postgresql
  encoding: utf8
  reconnect: false
  database: NAMEOFDATABASE
  pool: 5
  username: USERNAME
  password: PASSWORD
  host: localhost</pre><p> </p>
<p>Don&#8217;t forget to change the pertinent parts.</p>
<p>With this we can create our first migration to get the database to have the right table information. So let&#8217;s create that file:</p>
<p></p><pre class="crayon-plain-tag">class CreatePages &lt; ActiveRecord::Migration
  def change
    create_table :pages do |t|
      t.string :name
      t.string :handle
      t.text :body_text

      t.timestamps
    end
  end
end</pre><p> </p>
<p><a href="http://guides.rubyonrails.org/migrations.html">So that&#8217;s a mouthful that&#8217;s easier explained in the Rails guide.</a> In short this creates a table with the listed columns. By default the id primary column is create for you, as well as an automatic &#8220;created_at&#8221; and &#8220;updated_at&#8221; columns too.</p>
<p>To run our migration you need to run <code>bundle exec rake db:migrate</code>. This occurs whenever you need to run any database migrations.</p>
<p>And now let&#8217;s update our Page model:</p>
<p></p><pre class="crayon-plain-tag">class Page &lt; ActiveRecord::Base
  validates_presence_of :name
  validates_length_of :name, minimum: 3
end</pre><p> </p>
<p>Yep, it is that small. Rails is smart enough to know that the attributes is the name of the columns. It also includes a finder method and handles saving to the database for you. Of course we need to create the &#8220;create page&#8221; page since we have an empty database:</p>
<p></p><pre class="crayon-plain-tag">class PagesController &lt; ApplicationController
  def new
    @page = Page.new
    render :action=&gt;:edit
  end

  def create
    @page = Page.new
    @page.name = params['page']['name']
    @page.handle = params['page']['handle']
    @page.body_text = params['page']['body_text']
    if @page.save
      redirect_to @page
    else
      render :action=&gt;:edit
    end
  end

  def show
    @page = Page.find(params[:id])
  end

  def edit
    @page = Page.find(params[:id])
  end

  def update
    @page = Page.find(params[:id])
    @page.name = params['page']['name']
    @page.handle = params['page']['handle']
    @page.body_text = params['page']['body_text']
    if @page.save
      redirect_to @page
    else
      render :action=&gt;:edit
    end
  end
end</pre><p> </p>
<p>Notice how we don&#8217;t even need to create a new form? It can re-use the same form because it knows that the data is a new entry instead of an old entry and redirects accordingly.</p>
<p>Lastly, there&#8217;s associations, <a href="http://guides.rubyonrails.org/association_basics.html">which you can read on the Rails guide</a>. We&#8217;ll be going into associations when we start the main project, but for now the guide will do.</p>
<p>And that gets you up to speed with all the major parts of Rails. There&#8217;s still tons more to learn, but there&#8217;s better guides for what you need after this point:</p>
<ul>
<li><a href="http://guides.rubyonrails.org/active_record_querying.html">How to query the database to get certain items or groupings</a></li>
<li><a href="http://guides.rubyonrails.org/action_mailer_basics.html">How to send email</a></li>
<li><a href="http://guides.rubyonrails.org/asset_pipeline.html">All about the asset pipeline that takes care of CSS and Javascript files for you</a></li>
</ul>
<p>And that&#8217;s it. This last part is <a href="https://github.com/ROFISH/ruby_for_programmers">available on Github</a>.</p>
]]></content:encoded>
			</item>
		<item>
		<title>Ruby for Programmers – Part 16: Data Models</title>
		<link>http://rofish.net/2014/02/ruby-for-programmers-part-16-data-models/</link>
		<pubDate>Mon, 10 Feb 2014 03:35:23 +0000</pubDate>
		<dc:creator><![CDATA[Ryan Alyea]]></dc:creator>
				<category><![CDATA[Ruby For Programmers]]></category>

		<guid isPermaLink="false">http://rofish.net/?p=152</guid>
		<description><![CDATA[By now we can render stuff to a webpage, which is cool, but there&#8217;s no way to make or save any data, so let&#8217;s fix that. Since we&#8217;re making a CMS thing, we&#8217;re going to need the ability to make &#8230; <a href="http://rofish.net/2014/02/ruby-for-programmers-part-16-data-models/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
				<content:encoded><![CDATA[<p>By now we can render stuff to a webpage, which is cool, but there&#8217;s no way to make or save any data, so let&#8217;s fix that. Since we&#8217;re making a CMS thing, we&#8217;re going to need the ability to make and save data. So let&#8217;s start by making a silly flat-file data-model system in a new folder &#8220;db&#8221;:</p>
<p></p><pre class="crayon-plain-tag">[{"id":1,"name":"Page","body_text":"&lt;p&gt;This is a page.&lt;/p&gt;","handle":"page-1"},{"id":1,"name":"Page 2","body_text":"&lt;p&gt;This is another page.&lt;/p&gt;","handle":"page-2"}]</pre><p> </p>
<p>To work with this data, we&#8217;re going to create a special class called &#8220;Page&#8221; to handle our pages. Generally speaking, any class that exclusively deals with data is called a &#8220;model&#8221;. Thus, our new file is going to be put in app/models/page.rb:</p>
<p></p><pre class="crayon-plain-tag">class Page

# class methods

  class &lt;&lt; self
    def where(predecate)
      raise ArgumentError.new("predecate must be a hash!") unless predecate.is_a?(Hash)
      load_data

      # this isn't the best way to do this (maybe via inject), but to show for example
      # for all the data rows
      found_data = @data.select do |row|
        has_all_conditions = true
        # check to see if the row supports all our conditions by using the AND statement
        predecate.each do |key, value|
          has_all_conditions = has_all_conditions &amp;&amp; row[key.to_s] == value
        end
        # if it has all conditions, then this is true
        has_all_conditions
      end
      found_data.map{|x| Page.new(x)}
    end

    private

    def load_data
      return true if @loaded
      rawdata = File.read(File.join(Rails.root,'db','pages.json'))
      @data = JSON::load(rawdata)
    end
  end


# instance methods

  def initialize(data)
    @data = data
  end

  def id
    @data['id']
  end

  def name
    @data['name']
  end

  def body_text
    @data['body_text']
  end

  def handle
    @data['handle']
  end

end</pre><p> </p>
<p>This is a bunch of code to drop, but all it really does is load a JSON file and allows you to search for data.</p>
<p>And let&#8217;s modify our controller and view to use the new page data:</p>
<p></p><pre class="crayon-plain-tag">class MainpageController &lt; ApplicationController
  def index
  end

  def show
    @page = Page.where(handle:params[:id]).first

    if @page.blank?
      render text: "&lt;h1&gt;404 Not Found&lt;/h1&gt;", status: 404
    end

    #implicit render
  end
end</pre><p> </p>
<p></p><pre class="crayon-plain-tag">&lt;h1&gt;&lt;%= @page.name %&gt;&lt;/h1&gt;
&lt;%# Be very, very careful when using html_safe! %&gt;
&lt;%= @page.body_text.html_safe %&gt;</pre><p> </p>
<p>If you just browse to &#8220;/page/page-2&#8221;, it will show the data for that page. Now that&#8217;s nice, but we can make it better.</p>
<p>Let&#8217;s start adding some Rails methods to the Page class to start adding some magic. We&#8217;re going to start with ActiveModel, which contains a bit of magic without requiring much more. So first let&#8217;s add it to our Gemfile:</p>
<p></p><pre class="crayon-plain-tag">ruby '2.1.0'
source 'https://rubygems.org'
gem 'rack', '~&gt;1.5.2'
gem 'actionpack', '~&gt; 4.1.0.beta1'
gem 'actionview', '~&gt; 4.1.0.beta1'
gem 'railties', '~&gt; 4.1.0.beta1'
gem 'activemodel', '~&gt; 4.1.0.beta1'</pre><p> </p>
<p>And add it to our list of railties to preload it:</p>
<p></p><pre class="crayon-plain-tag">require File.expand_path('../boot', __FILE__)

require 'rails'
require 'action_controller/railtie'
require 'action_view/railtie'
require 'active_model/railtie'

Bundler.require

module GenericCMS
  class Application &lt; Rails::Application
    # you could put some custom stuff here if you wanted

    config.secret_key_base = "rails really wants this to be defined"
  end
end</pre><p> </p>
<p>And so now we can add some specialized functions. First is ActiveModel::Model which adds some internal specialized functions:</p>
<ul>
<li><a href="https://github.com/rails/rails/blob/v4.1.0.beta1/activemodel/lib/active_model/naming.rb">ActiveModel::Naming</a> &#8211; which creates string names from your class names. Very useful for generating routes (and table names later on).</li>
<li><a href="https://github.com/rails/rails/blob/v4.1.0.beta1/activemodel/lib/active_model/translation.rb">ActiveModel::Translation</a> &#8211; which automatically creates human names from the attribute name, and allows you to translate them to other languages if the translation file is available.</li>
<li><a href="https://github.com/rails/rails/blob/v4.1.0.beta1/activemodel/lib/active_model/conversion.rb">ActiveModel::Conversion</a> &#8211; which adds a few helper functions for routing</li>
<li><a href="https://github.com/rails/rails/blob/v4.1.0.beta1/activemodel/lib/active_model/validations.rb">ActiveModel::Validations</a> &#8211; which we&#8217;ll get into a little bit later</a></li>
<li>And a few internal methods like automatically creating the initialize function for us.</li>
<p>So let&#8217;s add it:</p>
<p></p><pre class="crayon-plain-tag">class Page

  include ActiveModel::Model
  attr_accessor :id, :name, :body_text, :handle

# class methods

  class &lt;&lt; self
    def where(predecate)
      raise ArgumentError.new("predecate must be a hash!") unless predecate.is_a?(Hash)
      load_data

      # this isn't the best way to do this (maybe via inject), but to show for example
      # for all the data rows
      found_data = @data.select do |row|
        has_all_conditions = true
        # check to see if the row supports all our conditions by using the AND statement
        predecate.each do |key, value|
          has_all_conditions = has_all_conditions &amp;&amp; row[key.to_s] == value
        end
        # if it has all conditions, then this is true
        has_all_conditions
      end
      found_data.map{|x| Page.new(x)}
    end

    private

    def load_data
      return true if @loaded
      rawdata = File.read(File.join(Rails.root,'db','pages.json'))
      @data = JSON::load(rawdata)
    end
  end


# instance methods

end</pre><p> </p>
<p>That&#8217;s already better, but we have no way of saving. So let&#8217;s add that:</p>
<p></p><pre class="crayon-plain-tag">class Page

  include ActiveModel::Model
  attr_accessor :id, :name, :body_text, :handle

# class methods

  class &lt;&lt; self
    def where(predecate)
      raise ArgumentError.new("predecate must be a hash!") unless predecate.is_a?(Hash)
      load_data

      # this isn't the best way to do this (maybe via inject), but to show for example
      # for all the data rows
      found_data = @data.select do |row|
        has_all_conditions = true
        # check to see if the row supports all our conditions by using the AND statement
        predecate.each do |key, value|
          has_all_conditions = has_all_conditions &amp;&amp; row[key.to_s] == value
        end
        # if it has all conditions, then this is true
        has_all_conditions
      end
      found_data.map{|x| Page.new(x)}
    end

    private

    def load_data
      return true if @loaded
      rawdata = File.read(File.join(Rails.root,'db','pages.json'))
      @data = JSON::load(rawdata)
    end
  end


# instance methods

  def attributes
    {
      'id'        =&gt; @id,
      'name'      =&gt; @name,
      'body_text' =&gt; @body_text,
      'handle'    =&gt; @handle
    }
  end

  def save
    # get the raw data
    rawstring = File.read(File.join(Rails.root,'db','pages.json'))
    rawdata = JSON::load(rawstring)
    # delete this record's row
    rawdata.delete_if {|row| row['id'] == @id }
    # add the new record to the raw data
    rawdata &lt;&lt; attributes
    # save the raw data back to the file
    f = File.open(File.join(Rails.root,'db','pages.json'),'w')
    f.write rawdata.to_json
    f.close
    # return true so that we know it was successful
    true
  end

  def persisted?
    # this is always persisted with our flat files
    true
  end
end</pre><p> </p>
<p>Admittingly, not the most optimized flat-file format but we&#8217;ll figure that out later. Now that we can edit data and have added the ActiveModel::Conversion (via Model), we can now use resources on the routes. This is just an automatic route creator that does a bunch of magic for us.</p>
<p></p><pre class="crayon-plain-tag">Rails.application.routes.draw do
  get '/' =&gt; 'mainpage#index'
  resources :pages
end</pre><p> </p>
<p>Try a <code>bundle exec rake routes</code> to see what our routes looks like:</p>
<p></p><pre class="crayon-plain-tag">Prefix Verb   URI Pattern               Controller#Action
          GET    /                         mainpage#index
    pages GET    /pages(.:format)          pages#index
          POST   /pages(.:format)          pages#create
 new_page GET    /pages/new(.:format)      pages#new
edit_page GET    /pages/:id/edit(.:format) pages#edit
     page GET    /pages/:id(.:format)      pages#show
          PATCH  /pages/:id(.:format)      pages#update
          PUT    /pages/:id(.:format)      pages#update
          DELETE /pages/:id(.:format)      pages#destroy</pre><p> </p>
<p>So this creates a bunch of really common routes for us. Let&#8217;s use them. First we need a new class method called &#8220;find&#8221; that lets us find by a direct id number:</p>
<p></p><pre class="crayon-plain-tag">class Page

  include ActiveModel::Model
  attr_accessor :id, :name, :body_text, :handle

# class methods

  class &lt;&lt; self
    def find(id)
      load_data
      detected = @data.detect{|row| row['id'].to_s == id.to_s}
      raise "Not Found!" if detected.blank?
      Page.new(detected)
    end

    def where(predecate)
...</pre><p> </p>
<p>And create a new controller:</p>
<p></p><pre class="crayon-plain-tag">class PagesController &lt; ApplicationController
  def edit
    @page = Page.find(params[:id])
  end
end</pre><p> </p>
<p>And our edit page:</p>
<p></p><pre class="crayon-plain-tag">&lt;h1&gt;Editing &lt;%= @page.name %&gt;&lt;/h1&gt;
&lt;%= form_for @page do |f| %&gt;
  &lt;%= f.label :name %&gt;
  &lt;%= f.text_field :name %&gt;
  &lt;br/&gt;
  &lt;%= f.label :handle %&gt;
  &lt;%= f.text_field :handle %&gt;
  &lt;br/&gt;
  &lt;%= f.label :body_text %&gt;
  &lt;%= f.text_area :body_text,:rows=&gt;10,:cols=&gt;50 %&gt;
  &lt;br/&gt;
  &lt;%= f.submit %&gt;
&lt;% end %&gt;</pre><p> </p>
<p>This takes advantage of an ActionView form builder which automatically creates the form based on attributes and fills in the default value if it exists, and routes to the correct page if the resource routing exists.</p>
<p>Of course we need to create the update and show functions too:</p>
<p></p><pre class="crayon-plain-tag">class PagesController &lt; ApplicationController
  def show
    @page = Page.find(params[:id])
  end

  def edit
    @page = Page.find(params[:id])
  end

  def update
    @page = Page.find(params[:id])
    @page.name = params['page']['name']
    @page.handle = params['page']['handle']
    @page.body_text = params['page']['body_text']
    if @page.save
      redirect_to @page
    else
      render :action=&gt;:edit
    end
  end
end</pre><p> </p>
<p>Here we simply see the page attributes getting updated. Now that we have the ability to edit pages, lets throw some magic in the monkey works. First, callbacks:</p>
<p></p><pre class="crayon-plain-tag">class Page

  include ActiveModel::Model
  extend ActiveModel::Callbacks
  attr_accessor :id, :name, :body_text, :handle, :updated_at

  define_model_callbacks :save

  before_save :touch

# class methods

  class &lt;&lt; self
    def find(id)
      load_data
      detected = @data.detect{|row| row['id'].to_s == id.to_s}
      raise "Not Found!" if detected.blank?
      Page.new(detected)
    end

    def where(predecate)
      raise ArgumentError.new("predecate must be a hash!") unless predecate.is_a?(Hash)
      load_data

      # this isn't the best way to do this (maybe via inject), but to show for example
      # for all the data rows
      found_data = @data.select do |row|
        has_all_conditions = true
        # check to see if the row supports all our conditions by using the AND statement
        predecate.each do |key, value|
          has_all_conditions = has_all_conditions &amp;&amp; row[key.to_s] == value
        end
        # if it has all conditions, then this is true
        has_all_conditions
      end
      found_data.map{|x| Page.new(x)}
    end

    private

    def load_data
      return true if @loaded
      rawdata = File.read(File.join(Rails.root,'db','pages.json'))
      @data = JSON::load(rawdata)
    end
  end


# instance methods

  def attributes
    {
      'id'        =&gt; @id,
      'name'      =&gt; @name,
      'body_text' =&gt; @body_text,
      'handle'    =&gt; @handle,
      'updated_at'=&gt; @updated_at
    }
  end

  def save
    run_callbacks :save do
      # get the raw data
      rawstring = File.read(File.join(Rails.root,'db','pages.json'))
      rawdata = JSON::load(rawstring)
      # delete this record's row
      rawdata.delete_if {|row| row['id'] == @id }
      # add the new record to the raw data
      rawdata &lt;&lt; attributes
      # save the raw data back to the file
      f = File.open(File.join(Rails.root,'db','pages.json'),'w')
      f.write rawdata.to_json
      f.close
      # return true so that we know it was successful
      true
    end
  end

  def touch
    @updated_at = Time.now
  end

  def persisted?
    # this is always persisted with our flat files
    true
  end
end</pre><p> </p>
<p>You should be familiar with callbacks, and this is the same. You can define (or have defined for you), various callbacks. For instance, this touches a new &#8220;updated_at&#8221; attribute which might be useful.</p>
<p>Another useful module is ActiveModel::Validation which allows one to check to see if the data validations certain conditions. For example, you may want a name or title or not be blank and have a certain minimum. For example you could do this:</p>
<p></p><pre class="crayon-plain-tag">class Page

  include ActiveModel::Model
  extend ActiveModel::Callbacks
  attr_accessor :id, :name, :body_text, :handle, :updated_at

  define_model_callbacks :save

  before_save :touch

  validate :name_minimum_size

# class methods

  class &lt;&lt; self
    def find(id)
      load_data
      detected = @data.detect{|row| row['id'].to_s == id.to_s}
      raise "Not Found!" if detected.blank?
      Page.new(detected)
    end

    def where(predecate)
      raise ArgumentError.new("predecate must be a hash!") unless predecate.is_a?(Hash)
      load_data

      # this isn't the best way to do this (maybe via inject), but to show for example
      # for all the data rows
      found_data = @data.select do |row|
        has_all_conditions = true
        # check to see if the row supports all our conditions by using the AND statement
        predecate.each do |key, value|
          has_all_conditions = has_all_conditions &amp;&amp; row[key.to_s] == value
        end
        # if it has all conditions, then this is true
        has_all_conditions
      end
      found_data.map{|x| Page.new(x)}
    end

    private

    def load_data
      return true if @loaded
      rawdata = File.read(File.join(Rails.root,'db','pages.json'))
      @data = JSON::load(rawdata)
    end
  end


# instance methods

  def attributes
    {
      'id'        =&gt; @id,
      'name'      =&gt; @name,
      'body_text' =&gt; @body_text,
      'handle'    =&gt; @handle,
      'updated_at'=&gt; @updated_at
    }
  end

  def save
    return false if !valid?
    run_callbacks :save do
      # get the raw data
      rawstring = File.read(File.join(Rails.root,'db','pages.json'))
      rawdata = JSON::load(rawstring)
      # delete this record's row
      rawdata.delete_if {|row| row['id'] == @id }
      # add the new record to the raw data
      rawdata &lt;&lt; attributes
      # save the raw data back to the file
      f = File.open(File.join(Rails.root,'db','pages.json'),'w')
      f.write rawdata.to_json
      f.close
      # return true so that we know it was successful
      true
    end
  end

  def touch
    @updated_at = Time.now
  end

  def name_minimum_size
    if @name.nil?
      errors.add(:name, 'Must exist.')
    elsif @name.length &lt; 3
      errors.add(:name, 'Must have at least three characters.')
    end
  end

  def persisted?
    # this is always persisted with our flat files
    true
  end
end</pre><p> </p>
<p>But there are built-in validators for common validations:</p>
<p></p><pre class="crayon-plain-tag">class Page

  include ActiveModel::Model
  extend ActiveModel::Callbacks
  attr_accessor :id, :name, :body_text, :handle, :updated_at

  define_model_callbacks :save

  before_save :touch

  validates_presence_of :name
  validates_length_of :name, minimum: 3
...</pre><p> </p>
<p><a href="http://guides.rubyonrails.org/active_record_validations.html">The rest of the validators are on the Rails guide.</a></p>
<p>That&#8217;s the basics of attributes and how it can modify your saving. Now let&#8217;s focus on databases.</p>
<p>As always, <a href="https://github.com/ROFISH/ruby_for_programmers/tree/master/16">code examples are on Github</a>.</p>
]]></content:encoded>
			</item>
		<item>
		<title>Ruby for Programmers – Part 15: Action Packed Viewing</title>
		<link>http://rofish.net/2014/01/ruby-for-programmers-part-15-action-packed-viewing/</link>
		<pubDate>Mon, 20 Jan 2014 10:45:22 +0000</pubDate>
		<dc:creator><![CDATA[Ryan Alyea]]></dc:creator>
				<category><![CDATA[Ruby For Programmers]]></category>

		<guid isPermaLink="false">http://rofish.net/?p=149</guid>
		<description><![CDATA[So as I mentioned in the last part of rendered, we built a fairly simple rendering engine using Rails&#8217; built-in templating engine ERB. And that&#8217;s fine, but there&#8217;s still a lot of code in our controllers and Rails has a &#8230; <a href="http://rofish.net/2014/01/ruby-for-programmers-part-15-action-packed-viewing/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
				<content:encoded><![CDATA[<p>So as I mentioned in the last part of rendered, we built a fairly simple rendering engine using Rails&#8217; built-in templating engine ERB. And that&#8217;s fine, but there&#8217;s still a lot of code in our controllers and Rails has a full featured rendering system called ActionView, which not only includes the rendering methods but tons of helpers to build pre-filled forms, etc.</p>
<p>So first let&#8217;s add ActionView to our Gemfile:</p>
<p></p><pre class="crayon-plain-tag">ruby '2.1.0'
source 'https://rubygems.org'
gem 'rack', '~&gt;1.5.2'
gem 'actionpack', '~&gt; 4.1.0.beta1'
gem 'actionview', '~&gt; 4.1.0.beta1'
gem 'railties', '~&gt; 4.1.0.beta1'</pre><p> </p>
<p>And after a <code>bundle install</code>, ActionView is available. It also adds the &#8220;erubis&#8221; gem, which is better, safer, and faster ERB handling than the simple built-in ERB handler.</p>
<p>We&#8217;re also going to add the railtie to our application.rb just so that ActionView has access to the various Rails configuration files:</p>
<p></p><pre class="crayon-plain-tag">require File.expand_path('../boot', __FILE__)

require 'rails'
require 'action_controller/railtie'
require 'action_view/railtie'

Bundler.require

module GenericCMS
  class Application &lt; Rails::Application
    # you could put some custom stuff here if you wanted

    config.secret_key_base = "rails really wants this to be defined"
  end
end</pre><p> </p>
<p>And lastly, add the renderer to our controller:</p>
<p></p><pre class="crayon-plain-tag">class MainpageController &lt; ActionController::Metal
  include AbstractController::Rendering
  
  include ActionController::UrlFor
  include Rails.application.routes.url_helpers #required to tell UrlFor which routes to use
  include ActionController::Redirecting
  include ActionView::Rendering
  include ActionController::Rendering
  include ActionController::ImplicitRender

  include AbstractController::Callbacks
  include ActionController::Rescue
  include ActionController::Instrumentation

  before_filter :doing_stuff
  rescue_from ZeroDivisionError, with: :divided_by_zero

  prepend_view_path(File.join(Rails.root,'app','views'))

  def doing_stuff
    @hi = 'sup'
  end

  def index
  end

  def show
    if params[:id] == "1"
      # do nothing, thus implicit render
    else
      render text: "&lt;h1&gt;404 Not Found&lt;/h1&gt;", status: 404
    end
  end

  def divided_by_zero
    self.response_body = "&lt;h1&gt;You divided by zero. This is not allowed as you may break all of physics."
  end
end</pre><p> </p>
<p>In a Metal, you need to define where the views are location, such the line in #18. But notice that we got rid of all that rendering code. And our pages now render!</p>
<p>Going over all the different helpers would take far too long, so I&#8217;m just going to mention them as I get into them. The <a href="http://guides.rubyonrails.org/form_helpers.html">Guide on Form Helpers</a> is a better resource. However, there is a couple of big notes to add:</p>
<p>First, HTML safety. Nasty insertable HTML and Javascript to steal your cookies and delete your pages is everywhere, so we don&#8217;t want to trust anything from the database. So every String that passes through ActionView is sanitized unless it&#8217;s marked as safe. So for example, if we change our @hi variable to <code>@hi = '<br />
<h1>sup</h1>
<p>'</code>, then what gets outputted in our index is: Front Page! &lt;h1&gt;sup&lt;/h1&gt; It actually will convert so that it displays the HTML. This is a safety first option, but if for some reason you can trust the output, then you can use #.html_safe in the ERB to mark as safe:</p>
<p></p><pre class="crayon-plain-tag">&lt;h1&gt;Front Page! &lt;%= @hi.html_safe %&gt;&lt;/h1&gt;</pre><p> </p>
<p>This marks it as safe to straight output vs. sanitizing.</p>
<p>And secondly, layouts! Should be obviously useful as any webpage has the same headers and footers, so let&#8217;s render the inside from the outside. To enable, just change to ActionView::Layouts:</p>
<p></p><pre class="crayon-plain-tag">class MainpageController &lt; ActionController::Metal
  include AbstractController::Rendering
  
  include ActionController::UrlFor
  include Rails.application.routes.url_helpers #required to tell UrlFor which routes to use
  include ActionController::Redirecting
  include ActionView::Layouts
  include ActionController::Rendering
  include ActionController::ImplicitRender
...</pre><p> </p>
<p>And you&#8217;re good to go. While you can use the <a href="http://guides.rubyonrails.org/layouts_and_rendering.html#finding-layouts">ActionController#layout method to define custom layouts</a>, by default it uses the name of the controller to use as a layout. (If a layout doesn&#8217;t exist, then it will just render straight pages.) You put layouts in the app/views/layouts folder, separate from the controller views.</p>
<p>So let&#8217;s make a really simple layout:</p>
<p></p><pre class="crayon-plain-tag">&lt;!DOCTYPE html&gt;
&lt;html&gt;
&lt;head&gt;
&lt;title&gt;GenericCMS&lt;/title&gt;
&lt;/head&gt;
&lt;body&gt;
&lt;h1&gt;GenericCMS!&lt;/h1&gt;
&lt;p&gt;&lt;a href="/"&gt;Index page&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="/page/1"&gt;Page page&lt;/a&gt;&lt;/p&gt;
&lt;%= yield %&gt;
&lt;/body&gt;
&lt;/html&gt;</pre><p> </p>
<p>And that&#8217;s it! With the magic filename, you have included a layout. Note that for layouts to render their insides, you must include a yield, which returns the inside of the layout.</p>
<p>Just to finalize things up, we&#8217;re going to set the controller to ActionController::Base now:</p>
<p></p><pre class="crayon-plain-tag">class MainpageController &lt; ActionController::Base
  before_filter :doing_stuff
  rescue_from ZeroDivisionError, with: :divided_by_zero

  def doing_stuff
    @hi = '&lt;h1&gt;sup&lt;/h1&gt;'
  end

  def index
  end

  def show
    if params[:id] == "1"
      # do nothing, thus implicit render
    else
      render text: "&lt;h1&gt;404 Not Found&lt;/h1&gt;", status: 404
    end
  end

  def divided_by_zero
    self.response_body = "&lt;h1&gt;You divided by zero. This is not allowed as you may break all of physics."
  end
end</pre><p> </p>
<p>ActionController::Base is nothing but the Metal, but with all the batteries included. So it includes <strong>ALL</strong> the modules (and more!) that we&#8217;ve mentioned, preloads the view paths, and all that good stuff.</p>
<p>And just as a small detail, most Rails apps don&#8217;t have their controllers from the Base, but include an ApplicationController and use a hierarchical format:</p>
<p></p><pre class="crayon-plain-tag">class ApplicationController &lt; ActionController::Base
  before_filter :doing_stuff
  rescue_from ZeroDivisionError, with: :divided_by_zero

  def doing_stuff
    @hi = '&lt;h1&gt;sup&lt;/h1&gt;'
  end

  def divided_by_zero
    self.response_body = "&lt;h1&gt;You divided by zero. This is not allowed as you may break all of physics."
  end
end</pre><p> </p>
<p></p><pre class="crayon-plain-tag">class MainpageController &lt; ApplicationController
  def index
  end
...</pre><p> </p>
<p>Because of hierarchy, this allows the filters to act for all inherited controllers, and is typically a good idea to have all controllers inherit from this.</p>
<p>And that&#8217;s ActionController. We have now built a very, very fancy method of generating webpages, but there&#8217;s no meat here. We&#8217;ll be going over the basics of the form generation soon, but to do that, we need something to save against, so we&#8217;ll be working next on persistence.</p>
<p>If you want to get ahead in the next few lessons, <a href="http://www.postgresqltutorial.com/postgresql-select/">read up on the basics of SQL commands</a>. (We&#8217;ll eventually be using Postgres for this project.) However, unlike HTML where you need to know the basic tags and such, you technically don&#8217;t need to know anything about SQL since Rails/ActiveRecord completely abstracts it out. However, it&#8217;s good to know that the abstraction is just a fancy SQL generator, so knowing why it works gets a leg up.</p>
<p>As always, working code is available here: <a href="https://github.com/ROFISH/ruby_for_programmers/tree/master/15">https://github.com/ROFISH/ruby_for_programmers/tree/master/15</a></p>
]]></content:encoded>
			</item>
		<item>
		<title>Ruby for Programmers – Part 14: ERB My HTML!</title>
		<link>http://rofish.net/2014/01/ruby-for-programmers-part-14-erb-my-html/</link>
		<pubDate>Mon, 20 Jan 2014 05:38:31 +0000</pubDate>
		<dc:creator><![CDATA[Ryan Alyea]]></dc:creator>
				<category><![CDATA[Ruby For Programmers]]></category>

		<guid isPermaLink="false">http://rofish.net/?p=146</guid>
		<description><![CDATA[And now for something completely different. Let&#8217;s say you want to generate some HTML. Using interpolated strings is generally not a good idea as it can lead to unmaintainable code. The best way to handle this is through a templating &#8230; <a href="http://rofish.net/2014/01/ruby-for-programmers-part-14-erb-my-html/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
				<content:encoded><![CDATA[<p>And now for something completely different.</p>
<p>Let&#8217;s say you want to generate some HTML. Using interpolated strings is generally not a good idea as it can lead to unmaintainable code. The best way to handle this is through a templating engine, which is output text intermixed with code. Thankfully, Ruby itself contains it&#8217;s own built-in templating engine: ERB</p>
<p></p><pre class="crayon-plain-tag">require 'erb'

x = 42
template = ERB.new &lt;&lt;-EOF
  The value of x is: &lt;%= x %&gt;
EOF
p template.result(binding)

=&gt;  The value of x is: 42</pre><p> </p>
<p>&#8216;binding&#8217; is a special variable that is an object that contains the current variable scope. Yes, even scopes are objects that you can pass around. (Not recommended outside of template engines, as it messes with the garbage collector and may lead to memory leaks.)</p>
<p>There are three different tags to invoke:</p><pre class="crayon-plain-tag">&lt;% Ruby code -- inline with output %&gt;
&lt;%= Ruby expression -- replace with result %&gt;
&lt;%# comment -- ignored -- useful in testing %&gt;</pre><p> </p>
<p>The first allows one to write code before, and around, text. The second puts the result of code in the the output itself. The last is a way to write a comment. (You do write comments don&#8217;t you?)</p>
<p>So let&#8217;s add erb to our controller:</p><pre class="crayon-plain-tag">class MainpageController &lt; ActionController::Metal
  include AbstractController::Callbacks
  include ActionController::Instrumentation
  include ActionController::Rescue
  include ActionController::UrlFor
  include Rails.application.routes.url_helpers #required to tell UrlFor which routes to use
  include ActionController::Redirecting

  before_filter :doing_stuff
  rescue_from ZeroDivisionError, with: :divided_by_zero

  def doing_stuff
    @hi = 'sup'
  end

  def index
    template = ERB.new &lt;&lt;-EOF
&lt;h1&gt;Front Page!&lt;/h1&gt;
EOF
    self.response_body = template.result(binding)
  end

  def show
    template = ERB.new &lt;&lt;-EOF
&lt;pre&gt;&lt;%= params.to_yaml %&gt; &lt;%= params[:id] %&gt;&lt;/pre&gt;
EOF
    self.response_body = template.result(binding)
  end

  def divided_by_zero
    self.response_body = "&lt;h1&gt;You divided by zero. This is not allowed as you may break all of physics."
  end
end</pre><p> </p>
<p>But that doesn&#8217;t really abstract that out enough to be useful. However, we can now put the text into different files, which is even better! We&#8217;re going to put the views into app/views/CONTROLLERNAME/ACTIONNAME.html.erb :</p>
<p></p><pre class="crayon-plain-tag">&lt;h1&gt;Front Page! &lt;%= @hi %&gt;&lt;/h1&gt;</pre><p> </p>
<p></p><pre class="crayon-plain-tag">&lt;pre&gt;&lt;%= params.to_yaml %&gt; &lt;%= params[:id] %&gt;&lt;/pre&gt;</pre><p> </p>
<p></p><pre class="crayon-plain-tag">class MainpageController &lt; ActionController::Metal
  include AbstractController::Callbacks
  include ActionController::Instrumentation
  include ActionController::Rescue
  include ActionController::UrlFor
  include Rails.application.routes.url_helpers #required to tell UrlFor which routes to use
  include ActionController::Redirecting

  before_filter :doing_stuff
  rescue_from ZeroDivisionError, with: :divided_by_zero

  def doing_stuff
    @hi = 'sup'
  end

  def index
    template = ERB.new File.read(File.join(Rails.root,'app','views','mainpage','index.html.erb'))
    self.response_body = template.result(binding)
  end

  def show
    template = ERB.new File.read(File.join(Rails.root,'app','views','mainpage','show.html.erb'))
    self.response_body = template.result(binding)
  end

  def divided_by_zero
    self.response_body = "&lt;h1&gt;You divided by zero. This is not allowed as you may break all of physics."
  end
end</pre><p> </p>
<p>So as you can see in the controller, we&#8217;re pretty much doing the same thing, which means abstraction time and another new module: ActionController::ImplicitRender, which simply calls #render after the method is run:</p>
<p></p><pre class="crayon-plain-tag">class MainpageController &lt; ActionController::Metal
  include ActionController::Rescue
  include ActionController::UrlFor
  include Rails.application.routes.url_helpers #required to tell UrlFor which routes to use
  include ActionController::Redirecting
  include ActionController::ImplicitRender

  include AbstractController::Callbacks
  include ActionController::Instrumentation

  before_filter :doing_stuff
  rescue_from ZeroDivisionError, with: :divided_by_zero

  def doing_stuff
    @hi = 'sup'
  end

  def index
  end

  def show
  end

  def divided_by_zero
    self.response_body = "&lt;h1&gt;You divided by zero. This is not allowed as you may break all of physics."
  end

  def render(*args)
    template = ERB.new File.read(File.join(Rails.root,'app','views',params[:controller].to_s,"#{params[:action]}.html.erb"))
    self.response_body = template.result(binding)
  end
end</pre><p> </p>
<p>And let&#8217;s add some more programmability with that:</p>
<p></p><pre class="crayon-plain-tag">class MainpageController &lt; ActionController::Metal
  include AbstractController::Rendering
  
  include ActionController::UrlFor
  include Rails.application.routes.url_helpers #required to tell UrlFor which routes to use
  include ActionController::Redirecting
  include ActionController::Rendering
  include ActionController::ImplicitRender

  include AbstractController::Callbacks
  include ActionController::Rescue
  include ActionController::Instrumentation

  before_filter :doing_stuff
  rescue_from ZeroDivisionError, with: :divided_by_zero

  def doing_stuff
    @hi = 'sup'
  end

  def index
  end

  def show
    if params[:id] == "1"
      # do nothing, thus implicit render
    else
      render text: "&lt;h1&gt;404 Not Found&lt;/h1&gt;", status: 404
    end
  end

  def divided_by_zero
    self.response_body = "&lt;h1&gt;You divided by zero. This is not allowed as you may break all of physics."
  end

  def render_to_body(*args)
    if args.is_a?(Array) &amp;&amp; args.first.is_a?(Hash)
      options = args.first
    else
      options = {}
    end

    _process_options(options)

    if options[:text]
      options[:text]
    else
      template = ERB.new File.read(File.join(Rails.root,'app','views',params[:controller].to_s,"#{params[:action]}.html.erb"))
      template.result(binding)
    end
  end

  def rendered_format
    Mime::HTML
  end
end</pre><p> </p>
<p>This lets us pass some options and force a different type of render if we so please. In this case, it lets us give a specialized 404 error if the page id isn&#8217;t what we expect. You can render a text value and a status. But what if we wanted to render a different layout? Well all that, and more, is in the ActionView, a culmination of all the rendering points and more, in the next part.</p>
<p>As usual, working code examples are in my Github: <a href="https://github.com/ROFISH/ruby_for_programmers/tree/master/14">https://github.com/ROFISH/ruby_for_programmers/tree/master/14</a></p>
]]></content:encoded>
			</item>
		<item>
		<title>Ruby for Programmers – Meta 1: HTML</title>
		<link>http://rofish.net/2014/01/ruby-for-programmers-meta-1-html/</link>
		<pubDate>Mon, 13 Jan 2014 10:09:38 +0000</pubDate>
		<dc:creator><![CDATA[Ryan Alyea]]></dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://rofish.net/?p=144</guid>
		<description><![CDATA[Just in case you&#8217;re following from the blog, the next few parts will involve HTML rendering. Since these lessons are about Ruby / Rails, I&#8217;m going to assume that you know how to write HTML by hand, since we&#8217;ll be introducing &#8230; <a href="http://rofish.net/2014/01/ruby-for-programmers-meta-1-html/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
				<content:encoded><![CDATA[<p>Just in case you&#8217;re following from the blog, the next few parts will involve HTML rendering. Since these lessons are about Ruby / Rails, I&#8217;m going to assume that you know how to write HTML by hand, since we&#8217;ll be introducing a lot of magic functions that create HTML for you. If you don&#8217;t know how to HTML, Shay Howe wrote a wonderful <a href="http://learn.shayhowe.com/html-css/">HTML tutorial</a>, which is available on his website.</p>
<p>Shay&#8217;s tutorial goes into box models and typography early on, which is important for creating custom pages. But, I will be using <a href="http://getbootstrap.com">Bootstrap</a> as the default CSS theme for this tutorial. So instead of writing my own box models and typography CSS, I&#8217;ll be using Bootstrap&#8217;s CSS and HTML prescriptions.</p>
]]></content:encoded>
			</item>
		<item>
		<title>Ruby for Programmers – Part 13: Revving Some Metal</title>
		<link>http://rofish.net/2014/01/ruby-for-programmers-part-13-revving-some-metal/</link>
		<pubDate>Mon, 13 Jan 2014 09:30:31 +0000</pubDate>
		<dc:creator><![CDATA[Ryan Alyea]]></dc:creator>
				<category><![CDATA[Ruby For Programmers]]></category>

		<guid isPermaLink="false">http://rofish.net/?p=139</guid>
		<description><![CDATA[Earlier we had put together a basic controller and used the Routing and Metal to render some basic pages, but since we&#8217;re going to build a simple Generic Content Manager out of this, the parameters seem important. The method in &#8230; <a href="http://rofish.net/2014/01/ruby-for-programmers-part-13-revving-some-metal/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
				<content:encoded><![CDATA[<p>Earlier we had put together a basic controller and used the Routing and Metal to render some basic pages, but since we&#8217;re going to build a simple Generic Content Manager out of this, the parameters seem important. The method in which we got that information was out of a weird quirk of information that was automatically included in the env variable that was passed around. However, there&#8217;s better ways to get this.</p>
<p>This isn&#8217;t a module but just automatically included in Metal that I forgot in the last part. The params variable holds all the parameters that was sent to the page, including the GET parameters, POST parameters, and parameters set by the routing:</p><pre class="crayon-plain-tag">class MainpageController &lt; ActionController::Metal
  include AbstractController::Callbacks
  include ActionController::Instrumentation

  before_filter :doing_stuff

  def doing_stuff
    @hi = 'sup'
  end

  def index
    self.response_body = "&lt;h1&gt;Front Page #{@hi}&lt;/h1&gt;"
  end

  def show
    self.response_body = "&lt;pre&gt;#{params.to_yaml} #{params[:id]} #{Rails.logger.to_yaml}&lt;/pre&gt;"
  end
end</pre><p>We&#8217;re also going to add Instrumentation to the controller too. This adds tons more useful logging like page benchmarks and displays all the parameters. We also need to make a small change to our application.rb file too:</p><pre class="crayon-plain-tag">require File.expand_path('../boot', __FILE__)

require 'rails'
require 'action_controller/railtie'

Bundler.require

module GenericCMS
  class Application &lt; Rails::Application
    # you could put some custom stuff here if you wanted

    config.secret_key_base = "rails really wants this to be defined"
  end
end</pre><p>This adds the ActionController &#8216;railtie&#8217;, which adds useful information to the class like where the Rails log is, ability to have a config information in the config/environments folder, and the like. Don&#8217;t forget to restart your app, and you&#8217;ll notice more logging information on each page load. Cool:</p><pre class="crayon-plain-tag">Started GET "/page/asdasgs" for 127.0.0.1 at 2014-01-13 01:12:21 -0700
Processing by MainpageController#show as HTML
  Parameters: {"id"=&gt;"asdasgs"}
Completed 200 OK in 1ms</pre><p>What page and how long it took and what parameters, all useful information.</p>
<p>Rescue lets you create custom rescuables in case something goes wrong:</p><pre class="crayon-plain-tag">class MainpageController &lt; ActionController::Metal
  include AbstractController::Callbacks
  include ActionController::Instrumentation
  include ActionController::Rescue

  before_filter :doing_stuff
  rescue_from ZeroDivisionError, with: :divided_by_zero

  def doing_stuff
    @hi = 'sup'
  end

  def index
    self.response_body = "&lt;h1&gt;Front Page #{@hi}&lt;/h1&gt;"
  end

  def show
    1/0
    self.response_body = "&lt;pre&gt;#{params.to_yaml} #{params[:id]} #{Rails.logger.to_yaml}&lt;/pre&gt;"
  end

  def divided_by_zero
    self.response_body = "&lt;h1&gt;You divided by zero. This is not allowed as you may break all of physics."
  end
end</pre><p>Pretty simple, this detects a Ruby Exception (or a subclass of Exception) and lets you render a special page from a specially defined method. In this basic example, I divided by zero accidentally in my code and rescued from that error. I should note that this is controller-wide, mostly as a last-ditch failsafe to render a decent 500 or 404 error to a user rather than the built-in HTML files.</p><pre class="crayon-plain-tag">class MainpageController &lt; ActionController::Metal
  include AbstractController::Callbacks
  include ActionController::Instrumentation
  include ActionController::Rescue
  include ActionController::UrlFor
  include Rails.application.routes.url_helpers #required to tell UrlFor which routes to use
  include ActionController::Redirecting

  before_filter :doing_stuff
  rescue_from ZeroDivisionError, with: :divided_by_zero

  def doing_stuff
    @hi = 'sup'
  end

  def index
    #redirect_to "/show/butts"
    redirect_to :action=&gt;:show, :id=&gt;"butts"
  end

  def show
    self.response_body = "&lt;pre&gt;#{params.to_yaml} #{params[:id]} #{Rails.logger.to_yaml}&lt;/pre&gt;"
  end

  def divided_by_zero
    self.response_body = "&lt;h1&gt;You divided by zero. This is not allowed as you may break all of physics."
  end
end</pre><p>Redirecting just creates a simple #redirect_to function that creates all the HTTP parts necessary to redirect a browser to a different page. (For the SEOers in the crowd, by default it&#8217;s a 302 Found or temporary redirect, you can set it to 301 Moved Permanently or 303 Other if you so desire.)</p>
<p>UrlFor is a special class that helps you create URLs from your list of routes and the current route you are using. Note in the above it says :action=&gt;:show, :id=&gt;&#8221;butts&#8221;, (which I&#8217;m unsure why I used the older hash rocket style, but it&#8217;s a habit). In that case, it doesn&#8217;t define a controller so the UrlFor assumes that the controller is the one that I&#8217;m on. If you use redirect_to :id=&gt;&#8221;butts2&#8243; while in the #show action, then it&#8217;s the same as redirect_to :controller=&gt;&#8221;mainpage&#8221;, :action=&gt;&#8221;show&#8221;, :id=&gt;&#8221;butts2&#8243; since it will assume the same route elements for the ones that are missing. Very useful for dynamic URL making.</p>
<p>There&#8217;s a few more modules we could add, but it&#8217;s better to look at the code and read about it since those are more &#8220;as you need it&#8221;:</p>
<ul>
<li><a href="https://github.com/rails/rails/blob/master/actionpack/lib/action_controller/metal/http_authentication.rb">HttpAuthentication</a>: Allows you to set a HTTP user/password system managed by Rails (vs. being managed by the HTTP server or forwarder)</li>
<li><a href="https://github.com/rails/rails/blob/master/actionpack/lib/action_controller/metal/data_streaming.rb">DataStreaming</a>: Allows you to send files to the browser, either hosted and read directly by the forwarder, sent directly to Rack as a large string, or create dynamically generated files to force the browser to download (such as CSV files).</li>
<li><a href="https://github.com/rails/rails/blob/master/actionpack/lib/action_controller/metal/streaming.rb">Streaming</a>: A still-in-progress addition that allows one to render partials of a page. For example, render the top part with the CSS and Javascript, send that to the browser to chew on early, then render the rest of the page to send to the browser. Still requires lots of specialized support (ie. most middlewares and servers don&#8217;t support it), but pretty cool if it all fits together.</li>
<li><a href="https://github.com/rails/rails/blob/master/actionpack/lib/action_controller/metal/force_ssl.rb">ForceSSL</a>: A simple helper that enforces page loads over SSL and redirects if not on SSL. Useful for password pages and such.</li>
<li><a href="https://github.com/rails/rails/blob/master/actionpack/lib/action_controller/metal/cookies.rb">Cookies</a>: (<a href="https://github.com/rails/rails/blob/master/actionpack/lib/action_dispatch/middleware/cookies.rb">actual documentation here</a>), Simple cookie handling if for some reason you need tons of random cookies. (Note that we&#8217;ll be using Rail&#8217;s built-in session management to handle cookies for us, so you don&#8217;t explicitly need this. This is only if you want raw cookie access)</li>
<li><a href="https://github.com/rails/rails/blob/master/actionpack/lib/action_controller/metal/conditional_get.rb">ConditionalGet</a>: This handles HTTP caching on the user&#8217;s browser side. For example, you can tell a browser to keep a copy on a user&#8217;s computer and not download, thus saving time and bandwidth.</li>
</ul>
<p>That&#8217;s some of the magic functions and defaults available to a Controller. As you can see, these functions mostly just get and set various HTTP information for you. Next time, we&#8217;ll be rendering. No longer will the view data be in the in controller, we&#8217;ll put that into it&#8217;s own file with it&#8217;s own logic. Yay! (Also Session Management to store data in cookies.)</p>
<p>As usual, working code for this part is available here: https://github.com/ROFISH/ruby_for_programmers/tree/master/13</p>
]]></content:encoded>
			</item>
		<item>
		<title>Ruby for Programmers – Part 12: Totally Metal</title>
		<link>http://rofish.net/2014/01/ruby-for-programmers-part-12-totally-metal/</link>
		<pubDate>Mon, 13 Jan 2014 07:27:28 +0000</pubDate>
		<dc:creator><![CDATA[Ryan Alyea]]></dc:creator>
				<category><![CDATA[Ruby For Programmers]]></category>

		<guid isPermaLink="false">http://rofish.net/?p=135</guid>
		<description><![CDATA[Earlier, we briefly went over the controller as a way to store the methods of routes, but there&#8217;s way more to it then returning a bunch of status codes and headers. So now we&#8217;re going to add another piece of &#8230; <a href="http://rofish.net/2014/01/ruby-for-programmers-part-12-totally-metal/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
				<content:encoded><![CDATA[<p>Earlier, we briefly went over the controller as a way to store the methods of routes, but there&#8217;s way more to it then returning a bunch of status codes and headers. So now we&#8217;re going to add another piece of the pie, the ActionController, which is actually three different classes in increasing complexity, the AbstractController, the Metal, and the ActionController.</p>
<p>The AbstractController::Base just contains a base set of functions and modules that help out. Normally one wouldn&#8217;t make an AbstractController::Base, but this is just for show. So here&#8217;s our AbstractController:</p><pre class="crayon-plain-tag">class MainpageController &lt; AbstractController::Base
  def self.action(method)
    lambda do |env|
      controller = new
      controller.env = env
      controller.process(method)
    end
  end

  attr_accessor :env

  def index
    [200, {"Content-Type" =&gt; "text/html"}, ["&lt;h1&gt;Front Page&lt;/h1&gt;"]]
  end

  def show
    [200, {"Content-Type" =&gt; "text/html"}, ["&lt;pre&gt;asdf #{env['action_dispatch.request.path_parameters'][:id]}&lt;/pre&gt;"]]
  end
end</pre><p>So that doesn&#8217;t look much different then before. We still have to make our own self.action method. But we now have access to a few cool built-ins, the most important of which is the callback:</p><pre class="crayon-plain-tag">class MainpageController &lt; AbstractController::Base
  def self.action(method)
    lambda do |env|
      controller = new
      controller.env = env
      controller.process(method)
    end
  end

  include AbstractController::Callbacks

  attr_accessor :env
  before_filter :doing_stuff

  def doing_stuff
    @hi = 'sup'
  end

  def index
    [200, {"Content-Type" =&gt; "text/html"}, ["&lt;h1&gt;Front Page #{@hi}&lt;/h1&gt;"]]
  end

  def show
    [200, {"Content-Type" =&gt; "text/html"}, ["&lt;pre&gt;asdf #{env['action_dispatch.request.path_parameters'][:id]} #{@hi}&lt;/pre&gt;"]]
  end
end</pre><p>What it does, is allows a function to operate before all functions. On both pages, @hi is set. This is useful for tons of things like session management, page view counts, etc.</p>
<p>But, we still have to do that goofy array, so let&#8217;s get rid of it&#8230; with Metal. \__/</p>
<p>The ActionController Metal the base class that simply does what we already do with the array format and the action handle, but adds some sprinkles to make it look better. It&#8217;s only 235 lines long and doesn&#8217;t include much fluff.</p>
<p>So here&#8217;s our totally Metal controller:</p>
<p></p><pre class="crayon-plain-tag">class MainpageController &lt; ActionController::Metal
  include AbstractController::Callbacks

  before_filter :doing_stuff

  def doing_stuff
    @hi = 'sup'
  end

  def index
    self.response_body = "&lt;h1&gt;Front Page #{@hi}&lt;/h1&gt;"
  end

  def show
    self.response_body = "&lt;pre&gt;asdf #{env['action_dispatch.request.path_parameters'][:id]} #{@hi}&lt;/pre&gt;"
  end
end</pre><p></p>
<p>All the Metal really does is abstract out the env and the array, and also by default sets the content-type to &#8216;text/html&#8217;. Which is still a bonus because this controller is now starting to look good. It&#8217;s got some basic includes at the top, and just responds with basic text. At this point, all we did was abstract out the basics even more. Outside of including modules (like the Callback), the Metal is just a fancier version of our starting basic controller that&#8217;s not part of any class.</p>
<p>The Metal alone is perfectly serviceable, and some people prefer to use it. History lesson: the Rails Metal comes from the merge of Rails and Merb, where Merb was a from-the-ground-up system with plugins like I&#8217;m showing here.</p>
<p>Since we&#8217;re (mostly) done with abstracting out how to build a webpage, the next few segments will focus on the &#8216;batteries included&#8217; part of Rails.</p>
<p>A couple of extra notes about callbacks, first you can limit the callback, or even skip the callback, to specific functions. Just add the array of the functions:</p>
<p></p><pre class="crayon-plain-tag">before_filter :doing_stuff, only:[:index]
before_filter :doing_stuff, except:[:show]
skip_before_filter :doing_stuff</pre><p> </p>
<p>Skipping filters is useful for hierarchical class inheritance.</p>
<p>Also, when a callback returns with a response_body (or renders or redirects as we&#8217;ll see later), it skips the rest of the call stream. For example this:</p>
<p></p><pre class="crayon-plain-tag">class MainpageController &lt; ActionController::Metal
  include AbstractController::Callbacks

  before_filter :doing_stuff, only:[:index]
  before_filter :doing_stuff, except:[:show]
  skip_before_filter :doing_stuff

  def doing_stuff
    @hi = 'sup'
    self.response_body = "mystery callback"
  end

  def index
    self.response_body = "&lt;h1&gt;Front Page #{@hi}&lt;/h1&gt;"
  end

  def show
    self.response_body = "&lt;pre&gt;asdf #{env['action_dispatch.request.path_parameters'][:id]} #{@hi}&lt;/pre&gt;"
  end
end</pre><p> </p>
<p>Would always render &#8220;mystery callback&#8221; onto a page and never even run the #index or #show functions. This is another useful thing to be mindful of, and yet another powerful feature. For example, if you want to enforce a user login, then all you have to do is check if the user is logged in, and if not, redirect them to the login page. It will both not run the code they cannot use (since they are not logged in) and it will redirect them to a page where they can login. Useful!</p>
]]></content:encoded>
			</item>
		<item>
		<title>Ruby for Programmers – Part 11: Railtying It Together</title>
		<link>http://rofish.net/2014/01/ruby-for-programmers-part-11-railtying-it-together/</link>
		<pubDate>Mon, 06 Jan 2014 05:47:03 +0000</pubDate>
		<dc:creator><![CDATA[Ryan Alyea]]></dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://rofish.net/?p=130</guid>
		<description><![CDATA[Having all this on one script is okay for now, but it&#8217;s best to start splitting up files just to make it easier to follow. So let&#8217;s create some folder conventions for us: app/controllers will contain our controllers as determined &#8230; <a href="http://rofish.net/2014/01/ruby-for-programmers-part-11-railtying-it-together/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
				<content:encoded><![CDATA[<p>Having all this on one script is okay for now, but it&#8217;s best to start splitting up files just to make it easier to follow. So let&#8217;s create some folder conventions for us:</p>
<ul>
<li><em>app/controllers</em> will contain our controllers as determined by our routes</li>
<li><em>config/routes.rb</em> will contain the routes drawer</li>
<li><em>config/boot.rb</em> will contain the boot script</li>
<li><em>config/application.rb</em> will contain information specific to our application, and hold information between files.</li>
<li><em>config/environment.rb</em> will have the initializers after our application.</li>
<li><em>public/</em> will contain public files like CSS or error files</li>
</ul>
<p>So first in boot.rb we&#8217;ll put the require &#8216;bundler/setup&#8217;. Since it&#8217;s in another folder, we&#8217;re going to need to tell that the file is in another castle:</p>
<p></p><pre class="crayon-plain-tag"># Set up gems listed in the Gemfile.
ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../../Gemfile', __FILE__)

require 'bundler/setup' if File.exist?(ENV['BUNDLE_GEMFILE'])

# some more requires
require 'yaml'
require 'action_dispatch'

module Rails
  class &lt;&lt; self
    attr_accessor :application
  end

  class Application
    attr_accessor :routes

    class &lt;&lt; self
      def inherited(base)
        super
        Rails.application ||= base.instance
      end

      def instance
        @instance ||= new
      end
    end

    def routes
      @routes ||= ActionDispatch::Routing::RouteSet.new
      @routes.append(&amp;Proc.new) if block_given?
      @routes
    end
  end
end</pre><p> </p>
<p>ENV is a sweet built-in Ruby variable that contains the shell environment variables. This is useful if you want to store different configurations for different setups. Instead of different that may or may not be uploaded, it&#8217;s far better to store this information in an environment variable. You can setup this on the server so as to hide passwords or API keys too.</p>
<p>Below that is a really short version of the Rails application initializer. So we created a Rails module (for now think of modules as function containers), and made it so that Rails.application is accessible from anywhere. We then created a class named Application and used a Ruby auto-function named &#8220;inherited&#8221; where if a new class is made, it will run that function. In this case it sets Rails.application to a new instance of the child class. (If you&#8217;re confused, don&#8217;t worry, this is all automagicked away soon).</p>
<p>We also create the routes and the routes file:</p>
<p></p><pre class="crayon-plain-tag">Rails.application.routes.draw do
  get '/' =&gt; 'mainpage#index'
  get '/page/:id' =&gt; 'mainpage#show'
end</pre><p> </p>
<p>Which is just a copy/paste of our original routes. Note that it uses our Rails.application that was created, which means we need to create the child class to be inherited and instanced:</p>
<p></p><pre class="crayon-plain-tag">require File.expand_path('../boot', __FILE__)

Bundler.require

module GenericCMS
  class Application &lt; Rails::Application
    # you could put some custom stuff here if you wanted
  end
end

require File.expand_path('../../app/controllers/mainpage_controller', __FILE__)</pre><p> </p>
<p>Pretty boring here except this is where we create the class to be inherited. It also requires the boot file and mainpage_controller.rb file here too. mainpage_controller.rb itself is just a copy/paste:</p>
<p></p><pre class="crayon-plain-tag">class MainpageController
  def self.action(method)
    controller = self.new
    controller.method(method.to_sym)
  end

  def index(env)
    [200, {"Content-Type" =&gt; "text/html"}, ["&lt;h1&gt;Front Page&lt;/h1&gt;"]]
  end

  def show(env)
    [200, {"Content-Type" =&gt; "text/html"}, ["&lt;pre&gt;#{env['action_dispatch.request.path_parameters'][:id]}&lt;/pre&gt;"]]
  end
end</pre><p> </p>
<p>Exactly like the old one.</p>
<p>For now, our environment.rb will just include the application and the routes file:</p>
<p></p><pre class="crayon-plain-tag"># Load the Rails application.
require File.expand_path('../application', __FILE__)

# Load the Routes
require File.expand_path('../routes', __FILE__)</pre><p> </p>
<p>And config.ru will just include the environment.rb and run the routes:</p>
<p></p><pre class="crayon-plain-tag"># This file is used by Rack-based servers to start the application.

require ::File.expand_path('../config/environment',  __FILE__)
run Rails.application.routes</pre><p> </p>
<p>This boots and shows the same stuff as before with our routes.</p>
<p>You can view the working example here: <a href="https://github.com/ROFISH/ruby_for_programmers/tree/master/11/01_folder_structure">https://github.com/ROFISH/ruby_for_programmers/tree/master/11/01_folder_structure</a></p>
<p>Now before I go, there&#8217;s a reason why all this moving around, it&#8217;s just to show how Rails ties things together. In fact, the gem that holds all this together is &#8220;railties&#8221;. So let&#8217;s add it to our Gemfile, and update our scripts to use it:</p>
<p></p><pre class="crayon-plain-tag">ruby '2.1.0'
source 'https://rubygems.org'
gem 'rack', '~&gt;1.5.2'
gem 'actionpack', '~&gt; 4.1.0.beta1'
gem 'railties', '~&gt; 4.1.0.beta1'</pre><p> </p>
<p>And run <code>bundle install</code>. Now we only need to make a few small changes to a few files. boot.rb will get it&#8217;s Rails stuff removed since it&#8217;s now handled in the railties gem:</p>
<p></p><pre class="crayon-plain-tag"># Set up gems listed in the Gemfile.
ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../../Gemfile', __FILE__)

require 'bundler/setup' if File.exist?(ENV['BUNDLE_GEMFILE'])</pre><p> </p>
<p>environment.rb now tells Rails to initialize (which will auto-load important files like routes.rb):</p>
<p></p><pre class="crayon-plain-tag"># Load the Rails application.
require File.expand_path('../application', __FILE__)

# Initialize the Rails application.
Rails.application.initialize!</pre><p> </p>
<p>And config.ru will run Rails.application instead of the routes, since Rails will handle some automagic for us:</p>
<p></p><pre class="crayon-plain-tag"># This file is used by Rack-based servers to start the application.

require ::File.expand_path('../config/environment',  __FILE__)
run Rails.application</pre><p> </p>
<p>Since railties will automatically load the controller files for us, we just need to make a couple small modifications to our application.rb file:</p>
<p></p><pre class="crayon-plain-tag">require File.expand_path('../boot', __FILE__)

require 'rails'
require 'action_controller' #this only here as Rails complains if it's not available

Bundler.require

module GenericCMS
  class Application &lt; Rails::Application
    # you could put some custom stuff here if you wanted

    config.secret_key_base = "rails really wants this to be defined"
  end
end</pre><p> </p>
<p>We tell it to look for Rails and ActionController (which is next lesson, but railties/routing was whiny without it). Also, we started on the config because Rails complained without it.</p>
<p>And it works. <code>bundle exec rackup</code> will boot your app and it will still work like before, but now running on Rails. Once you load, you&#8217;ll notice it whining about eager_loading, so lets add an environment file config/environments/development.rb:</p>
<p></p><pre class="crayon-plain-tag">Rails.application.configure do
  # Settings specified here will take precedence over those in config/application.rb.

  # In the development environment your application's code is reloaded on
  # every request. This slows down response time but is perfect for development
  # since you don't have to restart the web server when you make code changes.
  config.cache_classes = false

  # Do not eager load code on boot.
  config.eager_load = false

  # Show full error reports and disable caching.
  config.consider_all_requests_local       = true
  #config.action_controller.perform_caching = false

  # Don't care if the mailer can't send.
  #config.action_mailer.raise_delivery_errors = false

  # Print deprecation notices to the Rails logger.
  config.active_support.deprecation = :log

  # Raise an error on page load if there are pending migrations.
  #config.active_record.migration_error = :page_load

  # Debug mode disables concatenation and preprocessing of assets.
  # This option may cause significant delays in view rendering with a large
  # number of complex assets.
  #config.assets.debug = true
end</pre><p> </p>
<p>You can ignore the actual settings until we need to go for them. However, this file is important because it defines some of the eager loading that makes Rails great. We&#8217;ll also add the default Rakefile too, while we&#8217;re at it.</p>
<p>Now you can run the app a different way <code>bundle exec rails server</code>. This boots the server a different way, but has all trimmings. rackup still works, but the rails server has better logging and debug files.</p>
<p>So this lesson just really moved things around, which is nice. But the controllers are still using the weird array output and a bad way to create HTML. So next lesson, let&#8217;s add some ActionControllers with some ActionViews.</p>
<p>The final code for this part is here: <a href="https://github.com/ROFISH/ruby_for_programmers/tree/master/11/02_railties">https://github.com/ROFISH/ruby_for_programmers/tree/master/11/02_railties</a></p>
]]></content:encoded>
			</item>
		<item>
		<title>Ruby for Programmers – Part 10: Actionpacked Routing!</title>
		<link>http://rofish.net/2014/01/ruby-for-programmers-part-10-actionpacked-routing/</link>
		<pubDate>Mon, 06 Jan 2014 05:06:07 +0000</pubDate>
		<dc:creator><![CDATA[Ryan Alyea]]></dc:creator>
				<category><![CDATA[Ruby For Programmers]]></category>

		<guid isPermaLink="false">http://rofish.net/?p=123</guid>
		<description><![CDATA[So as we saw in the last part, having different pages might end up being a slight pain, so let&#8217;s add some routing. First we&#8217;re going to need the actionpack gem, so lets add that to our Gemfile: [crayon-5c29b437cc777875312687/] Note &#8230; <a href="http://rofish.net/2014/01/ruby-for-programmers-part-10-actionpacked-routing/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
				<content:encoded><![CDATA[<p>So as we saw in the last part, having different pages might end up being a slight pain, so let&#8217;s add some routing. First we&#8217;re going to need the actionpack gem, so lets add that to our Gemfile:</p>
<p></p><pre class="crayon-plain-tag">ruby '2.1.0'
source 'https://rubygems.org'
gem 'rack', '~&gt;1.5.2'
gem "actionpack", "~&gt; 4.1.0.beta1"</pre><p> </p>
<p>Note that we&#8217;re going to be using the latest beta version because by the time this is done, the new version will be out. <img src="https://s.w.org/images/core/emoji/72x72/1f61b.png" alt="😛" class="wp-smiley" style="height: 1em; max-height: 1em;" /></p>
<p>Run <code>bundle install</code> to install your new gem.</p>
<p></p><pre class="crayon-plain-tag">Resolving dependencies...
Using i18n (0.6.9)
Using json (1.8.1)
Using minitest (5.2.0)
Using atomic (1.1.14)
Using thread_safe (0.1.3)
Using tzinfo (1.1.0)
Using activesupport (4.1.0.beta1)
Using builder (3.2.2)
Using erubis (2.7.0)
Using actionview (4.1.0.beta1)
Using rack (1.5.2)
Using rack-test (0.6.2)
Using actionpack (4.1.0.beta1)
Using bundler (1.5.1)
Your bundle is complete!
Use `bundle show [gemname]` to see where a bundled gem is installed.</pre><p> </p>
<p>Woah, that&#8217;s a lot of dependencies! We&#8217;ll eventually get to them as needed. But for now, we&#8217;re just going to include the routing part.</p>
<p>The config.ru allows the use of Middleware, or something that&#8217;s run before your app. So if you wish to use a something that automates something before every page call, such as routing, then you can make a Middleware. For a simple example, look at what happens when there&#8217;s an error in your code:</p>
<p></p><pre class="crayon-plain-tag">require 'rubygems'
require 'bundler/setup'
require 'yaml'

run Proc.new {|env|
  if env["PATH_INFO"] == "/"
    seymour.butts
    [200, {"Content-Type" =&gt; "text/html"}, ["&lt;h1&gt;Front Page&lt;/h1&gt;"]]
  else
    [404, {"Content-Type" =&gt; "text/html"}, ["&lt;h1&gt;Not Found&lt;/h1&gt;"]]
  end
}</pre><p> </p>
<p>Load that in your browser via <code>bundle exec rackup</code>. It will show the default Rack error page. But what if you want a fancier page? There&#8217;s a middleware for that: ActionDispatch::ShowExceptions . It will allow us to show webpages to status errors so that the end-user doesn&#8217;t see code errors. It&#8217;s real simple to add, first add the files to a new folder &#8220;public&#8221;, and individual status codes like so:</p>
<p><a href="http://rofish.net/wp-content/uploads/2014/01/Screen-Shot-2014-01-05-at-6.03.08-PM.png"><img src="http://rofish.net/wp-content/uploads/2014/01/Screen-Shot-2014-01-05-at-6.03.08-PM-300x225.png" alt="Screen Shot 2014-01-05 at 6.03.08 PM" width="300" height="225" class="alignnone size-medium wp-image-125" srcset="http://rofish.net/wp-content/uploads/2014/01/Screen-Shot-2014-01-05-at-6.03.08-PM-300x225.png 300w, http://rofish.net/wp-content/uploads/2014/01/Screen-Shot-2014-01-05-at-6.03.08-PM.png 391w" sizes="(max-width: 300px) 100vw, 300px" /></a></p>
<p>You can get the HTML for those pages in the public example on Github.</p>
<p>Why is the folder called &#8220;public&#8221;? Because I said so. (It&#8217;s a Rails convention actually.)</p>
<p>Then add the following to your config.ru:</p>
<p></p><pre class="crayon-plain-tag">require 'rubygems'
require 'bundler/setup'
require 'yaml'

require 'action_dispatch'

use ActionDispatch::ShowExceptions, ActionDispatch::PublicExceptions.new("public/")
run Proc.new {|env|
  if env["PATH_INFO"] == "/"
    seymour.butts
    [200, {"Content-Type" =&gt; "text/html"}, ["&lt;h1&gt;Front Page&lt;/h1&gt;"]]
  else
    [404, {"Content-Type" =&gt; "text/html"}, ["&lt;h1&gt;Not Found&lt;/h1&gt;"]]
  end
}</pre><p></p>
<p>The new line means to use the middleware ActionDispatch::ShowExceptions, with the argument of &#8220;ActionDispatch::PublicExceptions.new(&#8220;public/&#8221;)&#8221;. In this case, ActionDispatch::ShowExceptions requires a secondary middleware to route to actually show the exception. The &#8220;public/&#8221; of course means to look for any files in our newly created public folder.</p>
<p>Then load your front page. It should now have a prettier error page:</p>
<p><a href="http://rofish.net/wp-content/uploads/2014/01/Screen-Shot-2014-01-05-at-6.05.41-PM.png"><img src="http://rofish.net/wp-content/uploads/2014/01/Screen-Shot-2014-01-05-at-6.05.41-PM-300x102.png" alt="Screen Shot 2014-01-05 at 6.05.41 PM" width="300" height="102" class="alignnone size-medium wp-image-127" srcset="http://rofish.net/wp-content/uploads/2014/01/Screen-Shot-2014-01-05-at-6.05.41-PM-300x102.png 300w, http://rofish.net/wp-content/uploads/2014/01/Screen-Shot-2014-01-05-at-6.05.41-PM-500x170.png 500w, http://rofish.net/wp-content/uploads/2014/01/Screen-Shot-2014-01-05-at-6.05.41-PM.png 722w" sizes="(max-width: 300px) 100vw, 300px" /></a></p>
<p>It&#8217;s the little things that count.</p>
<p>So lets add some routing, so here&#8217;s our updated config.ru file:</p>
<p></p><pre class="crayon-plain-tag">require 'rubygems'
require 'bundler/setup'
require 'yaml'

require 'action_dispatch'

routes = ActionDispatch::Routing::RouteSet.new

routes.draw do
  get '/' =&gt; 'mainpage#index'
  get '/page/:id' =&gt; 'mainpage#show'
end

class MainpageController
  def self.action(method)
    controller = self.new
    controller.method(method.to_sym)
  end

  def index(env)
    [200, {"Content-Type" =&gt; "text/html"}, ["&lt;h1&gt;Front Page&lt;/h1&gt;"]]
  end

  def show(env)
    [200, {"Content-Type" =&gt; "text/html"}, ["&lt;pre&gt;#{env['action_dispatch.request.path_parameters'][:id]}&lt;/pre&gt;"]]
  end
end

use ActionDispatch::ShowExceptions, ActionDispatch::PublicExceptions.new("public/")
use ActionDispatch::DebugExceptions
run routes</pre><p> </p>
<p>So let&#8217;s go over what we did. First, we created a new RouteSet, which is fine, and then started to draw some routes. Notice how the routes mention a &#8220;mainpage#index&#8221; or &#8220;mainpage#show&#8221;? It means that to route that to a MainpageController#index or MainpageController#show action. Why does it add Controller to the class name? Because I say so.</p>
<p>On the MainpageController is a self.action handler to handle the route internals by creating a new instance. And the individual methods now look like before with the status, header, body like in the other example.</p>
<p>Towards the end we add ActionDispatch::DebugExceptions to show the errors in the log in our terminal, because errors are now hidden from the browser. And finally, our app is no longer a function but rather the routes we created (which will forward to it&#8217;s respective controller).</p>
<p>Anyway, the routes are exactly like Rails routes, so a better documentation was written in the <a href="http://guides.rubyonrails.org/routing.html">Rails Guide</a>. There is some fancy pants stuff other than generating each individual route, like &#8220;namespace&#8221; which allows you to create namespaced controllers (like Admin::PostController for an admin interface), &#8220;resources&#8221; which creates the standard routes for an object (index, show, new, edit, create, update, destroy), and constraints by regex, subdomain, and more.</p>
<p>We&#8217;ll be going over the part of routes we&#8217;ll be adding as we add them. This just shows how routes fits in the whole scheme.</p>
<p>Download the working example code here: <a href="https://github.com/ROFISH/ruby_for_programmers/tree/master/10">https://github.com/ROFISH/ruby_for_programmers/tree/master/10</a></p>
]]></content:encoded>
			</item>
		<item>
		<title>Ruby for Programmers – Part 9: Making Pages With Bundler and Rack</title>
		<link>http://rofish.net/2014/01/ruby-for-programmers-part-9-making-pages-with-bundler-and-rack/</link>
		<pubDate>Mon, 06 Jan 2014 00:34:26 +0000</pubDate>
		<dc:creator><![CDATA[Ryan Alyea]]></dc:creator>
				<category><![CDATA[Ruby For Programmers]]></category>

		<guid isPermaLink="false">http://rofish.net/?p=118</guid>
		<description><![CDATA[So ends the really basic tutorial. There&#8217;s still tons more stuff to go over, like Modules and Mixins, Monkeypatching, Begin/Rescue/Ensure, but we&#8217;ll get to those basics as we come to them. If you really want to learn some deep dark &#8230; <a href="http://rofish.net/2014/01/ruby-for-programmers-part-9-making-pages-with-bundler-and-rack/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
				<content:encoded><![CDATA[<p>So ends the really basic tutorial. There&#8217;s still tons more stuff to go over, like Modules and Mixins, Monkeypatching, Begin/Rescue/Ensure, but we&#8217;ll get to those basics as we come to them. If you really want to learn some deep dark mysteries, I suggest reading the <a href="http://pragprog.com/book/ruby4/programming-ruby-1-9-2-0">Pickaxe Book</a>. It&#8217;s a complete, unabridged, and also includes information about the standard library too.</p>
<p>So for now, we&#8217;re going to focus on creating a web app with Rails. There are other Ruby-based frameworks like Sinatra, we&#8217;re going to be focusing on Rails since it&#8217;s got, at least in my opinion, the right amount automagic for what we&#8217;re going to build. (Of course one could argue that Node or Java or some other language would be better. That&#8217;s not the scope of this, but to learn Rails.)</p>
<p>I&#8217;ve always found it better to learn Rails from the ground-up from its parts rather than a &#8220;here&#8217;s all the random things it can do!&#8221; that&#8217;s in most docs/tutorials. So to build a webpage from scratch, you must first invent the universe.</p>
<p>In which case, you must start with a Gemfile and <a href="http://bundler.io">Bundler</a>. In the dayes of olde, gems were not included with Ruby, but rather a separate installation. These days, it&#8217;s included with the Ruby source as part of a <a href="http://rofish.net/2012/11/ruby-for-programmers-part-0-using-ruby/">standard installation</a>. However, what&#8217;s missing is a package version manager, which is Bundler. You can install bundler as you would any other gem:</p>
<p></p><pre class="crayon-plain-tag">gem install bundler</pre><p> </p>
<p>Bundler ensures that everybody is running the same version of gem as you, which is very important as APIs and functions changes, and helps ensure security updates by listing gem versions.</p>
<p>So for now, we&#8217;re going to create a Gemfile in our project and list Rack as a gem:</p>
<p></p><pre class="crayon-plain-tag">ruby '2.1.0'
source 'https://rubygems.org'
gem 'rack', '~&gt;1.5.2'</pre><p> </p>
<p>Bundler allows a bunch of configuration options in the Gemfile (which can be read in the <a href="http://bundler.io/v1.5/gemfile.html">Bundler docs</a>). To note the current lines, the first tells Bundler to enforce a Ruby version. This is slightly helpful if you have a custom installation on a server, but especially helpful on cloud services like Heroku which otherwise wouldn&#8217;t know which Ruby version to use. (You don&#8217;t automatically want to use the latest and greatest because it might introduce bugs.) The second determines where the gems will download from (always rubygems.org). Then list the gems by name, and optionally by version. You can do the normal >, >=, <, <= tags, but ~> is special. It means that &#8220;incrementing the last number is okay, but not the others&#8221;. In this case Bundler can safely install 1.5.2, 1.5.3, 1.5.1052, but not 1.6.0. Also note that when installing on a server, Bundler will install the exact gem version you have from the Gemfile.lock file.</p>
<p>To install your gems just run <code>bundle install</code> from where your Gemfile is. This will create the Gemfile.lock which will tell servers and other programmers which version to use. If you&#8217;re missing a version, running <code>bundle install</code> will install it. If you wish to change a version, update the Gemfile and run <code>bundle update rack</code> or whatever the name of the gem to update. This will re-run the dependency check and put the new version in.</p>
<p>Once you have Rack installed, now it&#8217;s time to use it. While Rack can be called from a method like anything else, Rack apps typically have a &#8220;config.ru&#8221; file which is just a special file it looks for to operate.</p>
<p>So to create our first Rack app, just insert the following into a new config.ru file:</p>
<p></p><pre class="crayon-plain-tag">require 'rubygems'
require 'bundler/setup'

run Proc.new {|env| [200, {"Content-Type" =&gt; "text/html"}, ["&lt;h1&gt;Hello Rack!&lt;/h1&gt;"]]}</pre><p> </p>
<p>The first two lines tells Ruby to include rubygems, a holdover from the previously said days where gems is not included but good to do anyway. The second runs the Gemfile and includes all of its requested gems. Then we tell Rack to run a very simple app, which is already returned as an array with three elements: the HTTP status code (200 for page info, 404 for not found, etc.), the headers in a Hash, then the body of the response. Note that the body of the response has to respond to #each for metaprogramming and lazy-loading reasons we&#8217;ll go over later. Just for now, let&#8217;s make it a single element Array with a String.</p>
<p>To run your app, just run <code>bundle exec rackup</code> on the command line. (Bundle also ensures that you run the right version from the command line too, how nice!) Then just open your browser to localhost:9292 (or whichever port it chooses), and your page now loads! Nice, neat, easy simple. Except that every page is the same. Lets view what&#8217;s in the env variable:</p>
<p></p><pre class="crayon-plain-tag">require 'rubygems'
require 'bundler/setup'
require 'yaml'

run Proc.new {|env| [200, {"Content-Type" =&gt; "text/html"}, ["&lt;pre&gt;#{env.to_yaml}&lt;/pre&gt;"]]}</pre><p> </p>
<p>Quit your app and restart to load new code. Reload the page to view all kinds of wonderful information:</p>
<p></p><pre class="crayon-plain-tag">---
GATEWAY_INTERFACE: CGI/1.1
PATH_INFO: "/"
QUERY_STRING: ''
REMOTE_ADDR: 127.0.0.1
REMOTE_HOST: localhost
REQUEST_METHOD: GET
REQUEST_URI: http://localhost:9292/
SCRIPT_NAME: ''
SERVER_NAME: localhost
SERVER_PORT: '9292'
SERVER_PROTOCOL: HTTP/1.1
SERVER_SOFTWARE: WEBrick/1.3.1 (Ruby/2.1.0/2013-12-25)
HTTP_HOST: localhost:9292
HTTP_USER_AGENT: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.9; rv:26.0) Gecko/20100101
  Firefox/26.0
HTTP_ACCEPT: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
HTTP_ACCEPT_LANGUAGE: en-us,en;q=0.5
HTTP_ACCEPT_ENCODING: gzip, deflate
HTTP_CONNECTION: keep-alive
HTTP_CACHE_CONTROL: max-age=0
rack.version:
- 1
- 2
rack.input: !ruby/object:Rack::Lint::InputWrapper
  input: !ruby/object:StringIO {}
rack.errors: !ruby/object:Rack::Lint::ErrorWrapper
  error: !ruby/object:IO {}
rack.multithread: true
rack.multiprocess: false
rack.run_once: false
rack.url_scheme: http
HTTP_VERSION: HTTP/1.1
REQUEST_PATH: "/"</pre><p> </p>
<p>So from here we can get the path requested and do things if we wanted to, like this:</p>
<p></p><pre class="crayon-plain-tag">require 'rubygems'
require 'bundler/setup'
require 'yaml'

run Proc.new {|env|
  if env["PATH_INFO"] == "/"
    [200, {"Content-Type" =&gt; "text/html"}, ["&lt;h1&gt;Front Page&lt;/h1&gt;"]]
  else
    [404, {"Content-Type" =&gt; "text/html"}, ["&lt;h1&gt;Not Found&lt;/h1&gt;"]]
  end
}</pre><p> </p>
<p>It&#8217;s not pretty, but it does either show front page if you go to http://localhost:9292/ and a 404 error if you go to http://localhost:9292/asdf.</p>
<p>So right here off the bat, it&#8217;s going to show lots of things that are different if you are coming from a generic PHP side of things. PHP is generally a server plugin that operates based on which file is being requested. Even if you&#8217;re doing mod_rewrite stuff, it still generally just requests a file. Any changes to the file is fine, as the script is run on each page load.</p>
<p>Here though, it&#8217;s an app in the background that accepts a real HTTP connection. The app has to be running and any changes requires a restart of the app. It&#8217;s more of a tradeoff though: Large apps can keep it&#8217;s compiled code in memory and respond quicker vs. parsing scripting on each page load. For Ruby, since the code parsing for large apps is fairly slow, the server model is used.</p>
<p>Not all is lost, you can simply put your app behind a reverse proxy (<a href="http://httpd.apache.org/docs/2.2/mod/mod_proxy.html">Apache instructions</a>, <a href="http://wiki.nginx.org/HttpProxyModule">Nginx instructions</a>). Now using straight Rackup and WEBrick (Ruby&#8217;s included web server in ruby) is not a good idea on the deploy-side. There&#8217;s better options for those that run your own servers, like <a href="http://unicorn.bogomips.org">Unicorn</a>, <a href="http://puma.io">Puma</a>, <a href="https://www.phusionpassenger.com">Passenger</a>, the latter available in both open-source and enterprise editions, and Heroku, Docker, and AWS Beanstalk on the cloud-side. We&#8217;ll be mostly focusing on app building rather than deployment for the most part.</p>
]]></content:encoded>
			</item>
	</channel>
</rss>
