Rails 5: Action Cable Demystified

Published by Michael de Silva on Friday, 24 April 2015


Screen%20shot%202015-04-25%20at%2000.37.31

This write up is based on @DHH's keynote on Rails 5 at RailsConf 2015 and I am providing snippets of code directly from his slides, apart from fixing one typo!


We start by creating a channel, where its related to the DOM element, by using data-behavior. It's also been namespaced under App.

Once the inbox Channel is instantiated, there's a call-back, the data received, which we've handled to update a simple count.

class App.inbox extends ActionCable.Channel
  channelName: 'inbox'
 ...(continued)


Code & Tech

Mixing in Namespaced Classes in Ruby, a Template Method implementation

Today I was searching on a means for mixing in a namespaced class into another class and stumbled onto a gist of mine that I had saved back in October 2013.

Here's w ...(continued)

Graceful locale-based content fallback in RefineryCMS

This hack took me through the refinerycms-i18n gem, and I discovered that it does not aid in achieving graceful content fallback, amongst other issues.

It should b ...(continued)

'DevOps': Killing the Developer?


Screen%20shot%202014-08-07%20at%2000.39.03

Preamble

I started this week sorting out some widgets for a couple code bases that I am looking after at work. One's a legacy CMS app (Ruby 1.8.7/Rails 2.x) th ...(continued)

DevOps

Simple Scalable Infrastructure with DigitalOcean, Terraform, and Docker

While my primary system is a Ma ...(continued)

'DevOps': Killing the Developer?


Screen%20shot%202014-08-07%20at%2000.39.03

Preamble

I started this week sorting out some widgets for a couple code bases that I am looking after at work. One's a legacy CMS app (Ruby 1.8.7/Rails 2.x) th ...(continued)

Getting to Grips with Chef via Knife-solo, Berkshelf, and Vagrant ~ Part One

To get started, I've put together an example chef-repo (a.k.a 'kitchen') chef-server-with-vagrant, which was set ...(continued)


Event Driven React JS Components via an Event-Emitter Mixin

Published by Michael de Silva on Saturday, 18 April 2015


React is great in terms of its virtual DOM, and JSX makes the code so much more readable.

When leveraging React in terms of Rails, I highly recommend the reactjs/react-rails gem as this integrates it with the help of the asset pipeline, allowing one to setup components in app/assets/javascripts/components thanks to a components.js manifest file.

However, I wanted to be able to trigger components to re-render using an event system such as Backbone.Events, although for this quick example, I will be using EventEmitter.

The above contrived example renders a component on screen and the button's click event triggers a re-render of the component, passing along the payload data.

Typically, React goes hand-in-hand with [Flux](https:/ ...(continued)

Deferred Pattern with JavaScript ES6 Promises

Published by Michael de Silva on Friday, 17 April 2015


Here's an initial example of deferred resolution of a promise, — although the done callback of the $.ajax call updates the UI outside the standard promise callbacks — the deferred nature can only be seen via Chrome's inspector once the click event is triggered.

The use of the deferred pattern could be cleaned up as follows, where the promise itself is resolved via the click event.

I came across this sort of implementation whilst having a conversation with Jordan Harband (@ljharb and he pointed me to some of this work, which is one of th ...(continued)

Tools for Developer Productivity

Published by Michael de Silva on Thursday, 12 March 2015


Here are some recent additions that I've made to my dev workflow.

HTTPie: a CLI, cURL-like tool for humans

https://github.com/jakubroztocil/httpie

Pick

https://github.com/thoughtbot/pick

Here's one of the OhMyZSH aliases I've made,

git_stash_apply(){ git stash apply $(git stash list | pick | awk 'NR==1{printf $1}' | cut -d : -f 1,3) }

There's More to Ruby Debugging Than puts()

Published by Michael de Silva on Friday, 27 February 2015


This is a worthwhile read, There's More to Ruby Debugging Than puts().

One of the most useful has been #method, with #source_location, #arity, #to_proc etc. I regularly work with Rails 4.2 and Ruby 2.2 — as such my debugger is byebug with pry-byebug.

A Treatise on Resolving Module Dependencies with ActiveSupport::Concern#append_features

Published by Michael de Silva on Tuesday, 17 February 2015


Here's a quick script to play with which details the process by which ActiveSupport::Concern resolves module dependencies by hooking into Method#included, Method#extended, and Method#append_features.

I'll include a snippet of the full-source below, which at least contains the gory details on internal mechanics. You'll find it far more useful to read this and then compare it with the output of my script excuting rails runner lib/scripts/concerns.rb, which gives a sense of context as to which bits are eval'd first

# Notice how module B's dependency on D is resolved by `ActiveSupport::Concern`
module B
  extend ActiveSupport::Concern

  @_dependencies = [D]

  def self.append_features(mod)
    super
    puts "B.append_features: mod=#{mod}, self=#{self}\n\n"
  end

  def self.included(mod)
    super
    puts "B.included: #{self} included in #{mod}\n\n"
   ...(continued)

Nygma - Signing and encrypting data with tools built-in to Rails 4

Published by Michael de Silva on Saturday, 29 November 2014


Screen%20shot%202014-11-29%20at%2013.57.27

Having stumbled on Signing and encrypting data with tools built-in to Rails I was quite pleased to see this approach use the same tools that Rails uses for encrypting the user session (cookie).

This lead me to building Nygma to allow encrypting tokens received from Stripe. Since this was built rather quickly, I haven't been able to document its API as I normally do, but I will be cleaning this up in due course.

For those curious engineers amongst us, Rails' encrypted cookie implementation looks like

    class EncryptedCookieJar #:nodoc:
      include ChainedCookieJars

      def initialize(parent_jar, key_generator, options = {})
        if ActiveSupport::LegacyKeyGenerator === key_generator
          raise "You didn't set config.secret_key_base, which is required for this cookie jar. " +
             ...(continued)

Mixing in Namespaced Classes in Ruby, a Template Method implementation

Published by Michael de Silva on Saturday, 22 November 2014


Today I was searching on a means for mixing in a namespaced class into another class and stumbled onto a gist of mine that I had saved back in October 2013.

Here's what I implemented today, and you'll find a link to the original Gist at the end of this post.

The essence of the approach is to simply call const_set on the base class, _klass, and in this example setting that constant to class of interest via Class.new(ClassOfInterest).

You would also see this being used in specs such as

MyFancyException = Class.new(StandardError)
raise MyFancyException

In this context, the receiver, self is in fact the class in which you call the above, so self.MyFancyException = Class.new(StandardError) would also be perfectly fine, although not strictly idiomatic Ruby, as most often the receiver is implicit.

module Snowden
  module Utility
    extend self

      class Response
        attr_reader :error_message

        def initia ...(continued)

Simple Scalable Infrastructure with DigitalOcean, Terraform, and Docker

Published by Michael de Silva on Monday, 03 November 2014


While my primary system is a Mac, I like to keep my development workflows as linux dependent as possible. Therefore, rather than relying on tools such as boot2docker, I setup a custom image of Ubuntu 14.04 with various tools installed along with Docker 1.3 using Packer

My build template can be found on Github. My workflow from this point onwards is to simply start my customised version of Ubuntu via vagrant up and ssh vagrant@10.33.33.33.

Docker Build

Last weekend, I focused on creating a docker build for Rails, Nginx, and Unicorn with a MySQL data store. My aim at the time was to build a proof of concept, so I broke this down into several sessions ...(continued)

Graceful locale-based content fallback in RefineryCMS

Published by Michael de Silva on Monday, 13 October 2014


This hack took me through the refinerycms-i18n gem, and I discovered that it does not aid in achieving graceful content fallback, amongst other issues.

It should be noted this bit of work focused on Refinery v2.0.9 and may not be entirely applicable with the current release.

My solution involved adding the following decorator,

puts "Overriding Refinery::Page - #{__FILE__[/(vendor[\/\w\.]+)/]}"

Refinery::Page.class_eval do

  # The `Refinery::Page.find_by_path_or_id` call in
  # `Refinery::PagesController#find_page` calls `Refinery::Page.find_by_path` if
  # `params[:path].friendly_id?` is true.
  #
  #   # With slugs scoped to the parent page we need to find a page by its full path.
  #   # For example with about/example we would need to find 'about' and then its child
  #   # called 'example' otherwise it may clash with another page called /example.
  #   def self.find_by_path(path)
  #     split_path = path.to_s.split('/').reject(&:blan ...(continued)

Inside the Shellshock Vulnerability: The 25-year old Bash bug

Published by Michael de Silva on Saturday, 04 October 2014


You'll find posts such as "Everything You Need To Know About The Shellshock Bug" covering the basics of the bug and how to locally test it out on your, Mac or linux desktop. TL;DR — give this a spin

-> % env X="() { :;} ; echo vulnerable" /bin/sh -c "echo stuff"
vulnerable
stuff

Notice how my Mac is infact vulnerable to this. But how do attackers leverage this against web servers running say, Apache?

Cloudflare have a fantastic write up Inside Shellshock: How hackers are using it to exploit systems providing simple examples that anyone can try via curl.

For example, take this

curl -H "User-Agent: () { :; }; /bin/eject" http://example.com/

Apache internally creates a variable HTTP_USER_AGENT=() { :; }; /bin/eject but this would only work if this variable is passed to bash. This article runs into various int ...(continued)