• Short MongoDB Fields with Mongoid

    Need to have shorter field name in MongoDB, but still use readable names in code?

    # Mongoid Timestamps
    include Mongoid::Timestamps::Short
    
    # fields
    field :aid, as: :application_id, type:String
    
    # one to one
    embeds_one :address, :store_as => :ad
    
    # collections
    field :aid, as: :application_id
    belongs_to :application, foreign_key: :aid
    
  • On Writing – Steven King

    Part biography and part writing advice. Both were interesting.

    The advise that jumped out is, Do The Work. For writing that’s writing and reading. Which translates well for most things into doing and learning/observing.

    On Writing

  • Rails Routes used in an Isolated Engine

    The Problem

    I have a rails application an want to add a blog engine to it. In this case the blogit engine. Things are working well until the layout is rendered. It uses the parent applications layout, which is what I want, but because it’s an isolated engine, it doesn’t have access to any of the parent applications helpers, including url helpers.

    My Solution

    If there’s a better way, please post in the comments.

    In the engines config block, I open it’s application helper and add a method_missing definition. Then I check the main_app helper, which is added when the engine is mounted, for a matching helper method, if found use it.

    /config/initializers/blogit.rb

    ...
    module Blogit
      module ApplicationHelper
        def method_missing method, *args, &block
          puts "LOOKING FOR ROUTES #{method}"
          if method.to_s.end_with?('_path') or method.to_s.end_with?('_url')
            if main_app.respond_to?(method)
              main_app.send(method, *args)
            else
              super
            end
          else
            super
          end
        end
    
        def respond_to?(method)
          if method.to_s.end_with?('_path') or method.to_s.end_with?('_url')
            if main_app.respond_to?(method)
              true
            else
              super
            end
          else
            super
          end
        end
      end
    end
    ...
    

    As a side note, the engine layout can be specified in /app/views/layouts/blogit/application.html.haml.

    Gotchas

    root_path and root_url are defined for the engine, so those still need to be handled differently. This issue could happend for any routes that overlap.

    (main_app||self).root_path
    

    And the other way if you want to link to the engines root_path. blogit is the engine_name.

    (blogit||self).root_path
    
  • Rails Blog Engines

    A list of mountable blog engines for Rails.

    Blogit

    Blogit Engine

    Blogit is a flexible blogging solution for Rails apps. It:

    • Is Rack based;
    • Is a complete MVC solution based on Rails engines;
    • Aims to work right out of the box but remain fully customisable.

    JABE

    JABE Blog Engine

    JABE is a bare bones blogging engine that is installed as a gem. It will grow as its needs do.

    This version is for Rails 3.1+

    Squeaky

    Squeaky Blog Engine

    Squeaky is a simple mountable Rails engine for making a squeaky clean blog.

    Hitchens

    Hitchens Blog Engine

    • Mountable blog engine for Rails 3.1+
    • Design/style agnostic – just a blog backend
    • Inspired by radar/forem
    • MIT-LICENSE.

    Kublog

    Kublog Blog Engine

    Kublog is a simple yet complete way to have a Product Blog that integrates with your apps user base. It includes social sharing, atom feeds and moderated comments.

    Built for Rails 3.1, Kublog is a complete stack, fully configurable solution.

    • Publish posts with the most basic and simple wysiwyg
    • Attach multiple images to your content
    • Share your posts on your Product’s Twitter Page and Facebook Fan Page
    • E-mail personalized versions of your posts to all your users
    • Optional background processing with Delayed Job
    • Moderated comments from apps users, apps admins, and visitors
    • Atom feed for main blog and individual post categories
  • Basic Rails Sitemap Setup

    A basic sitemap generator for building a sitemap on the fly. I’d like a better way, but since it’s hosted on heroku and the map isn’t too big yet, this should work for now.

    Add a route to handle building the XML

    # /app/controllers/static_controller.rb
    def sitemap
      xml = ::SitemapGenerator.create!('http://fixmycarin.com') do |map|
        map.add '', priority:0.9 , changefreq: :daily
        map.add '/faq', priority:0.7 , changefreq: :weekly
        map.add '/places', priority:0.7, changefreq: :weekly 
        map.add '/contact', priority:0.7, changefreq: :weekly 
    
        places = Place.all
        places.each{|u| map.add(place_path(u), lastmod:u.updated_at, changefreq: :weekly)}
      end
      render :xml => xml
    end
    

    Add a route to point to the above action

    #/config/routes.rb
    get 'sitemap.xml' => "static#sitemap"
    

    Add a link in the robots.txt file

    Sitemap: http://fixmycarin.com/sitemap.xml
    

    Add the class that creates the XML. I put it in app/lib or app/services. This was adapted from this gist

    # from: https://gist.github.com/288069
    require 'builder'
    
    class SitemapGenerator
      def initialize url
        @url = url
        yield(self) if block_given?
      end
    
      def add url, options = {}
        (@pages_to_visit ||= []) << options.merge(url:url)
        
      end
    
      def generate_sitemap
        xml_str = ""
        xml = Builder::XmlMarkup.new(:target => xml_str, :indent => 2)
    
        xml.instruct!
        xml.urlset(:xmlns=>'http://www.sitemaps.org/schemas/sitemap/0.9') {
          @pages_to_visit.each do |hash|
            unless @url == hash[:url]
              xml.url {
                xml.loc(@url + hash[:url])
                xml.lastmod(hash[:lastmod].utc.strftime("%Y-%m-%dT%H:%M:%S+00:00")) if hash.include? :lastmod
                xml.priority(hash[:priority]) if hash.include? :priority
                xml.changefreq(hash[:changefreq].to_s) if hash.include? :changefre
               }
            end
          end
        }
    
        return xml_str
      end
    
      # Notify popular search engines of the updated sitemap.xml
      def update_search_engines
        sitemap_uri = @url + 'sitemap.xml'
        escaped_sitemap_uri = CGI.escape(sitemap_uri)
        Rails.logger.info "Notifying Google"
        res = Net::HTTP.get_response('www.google.com', '/webmasters/tools/ping?sitemap=' + escaped_sitemap_uri)
        Rails.logger.info res.class
        Rails.logger.info "Notifying Yahoo"
        res = Net::HTTP.get_response('search.yahooapis.com', '/SiteExplorerService/V1/updateNotification?appid=SitemapWriter&url=' + escaped_sitemap_uri)
        Rails.logger.info res.class
        Rails.logger.info "Notifying Bing"
        res = Net::HTTP.get_response('www.bing.com', '/webmaster/ping.aspx?siteMap=' + escaped_sitemap_uri)
        Rails.logger.info res.class
        Rails.logger.info "Notifying Ask"
        res = Net::HTTP.get_response('submissions.ask.com', '/ping?sitemap=' + escaped_sitemap_uri)
        Rails.logger.info res.class
      end
    end
    
  • Open Up Localhost

    In many cases it might be easier/better to just use LocalTunnel.

    In this case, I didn’t want the external URL changing all the time, and I already have a Linode server setup that I can use. Here are some notes on setting it up.

    Assumes a Linux server setup with SSH and Apache.

    Setup the proxy

    Enable the proxy modules on the server.

    a2enmod proxy
    a2enmod proxy_http
    

    Edit mods-available/proxy.conf to enable the reverse proxy for requests.

    ProxyRequests Off
    
    <Proxy *>
    Order deny,allow
    Allow from all
    </Proxy>
    

    Add a new virtual site to be the reverse proxy. Place a file like the following in the sites-available Apache directory. The localhost port doesn’t matter too much, just needs to not be in use.

    <VirtualHost *:80>
         ServerAdmin dustt
         ServerName virtual.red27.net
         SetEnv proxy-initial-not-pooled 1
         ProxyPass / http://localhost:8001
         ProxyPassReverse / http://localhost:8001
         ProxyPreserveHost On
    </VirtualHost>
    

    Enamble the virtual site and restart Apache.

    a2ensite virtual.red27.net
    

    On the client

    You will need to SSH into the server and reverse forward the packets back to the local server.

    ssh -nNT -R 8001:localhost:3000 user@virtual.red27.net
    

    This tunnel will need to be reset if the local server errors out. Removing the n argument may help notify you if something goes wrong.

  • Node.JS Modules