Category Archives: Ruby + Rails

Rails + Webpack + Webpack-Manifest + React + Babel 7 + HMR – [chunkHash]

I’m writing this quick one up so you can save the 1.5 hours that I spent debugging this.

Terms :
HMR – HotModelReload – webpack-dev-server option to trigger browser-auto-refresh when webpack detects filechange (and re-compiles)

Here’s what I’m using :

  • Rails 5.2
  • Webpack-Manifest Gem
  • Yarn
    • Webpack (-cli)
    • Webpack-dev-server
    • @babel/core
    • @babel/preset-react

The issue : When running webpack-dev-server with --hot option (enable HotModelReloading, webpack compile fails with :

ERROR in chunk hello_react [entry]
js/[name]-[contenthash].js
Cannot use [chunkhash] or [contenthash] for chunk in 'js/[name]-[contenthash].js' (use [hash] instead)

Context : With Rails + Webpack-Manifest gem, webpack config is being used from ./config/webpack/environment.js (and it’s named siblings).

This SO discussed the problem and solution
https://stackoverflow.com/questions/50217480/cannot-use-chunkhash-or-contenthash-for-chunk-in-name-chunkhash-js-us
It does not unfortunately tell you very well what to do with

// 4th SO andswer of SO:50217480
output: {
    filename: process.env.production ? `bundle-[chunkHash].js` : `bundle-[hash].js`
}

Luckly, this SO includes a complete webpack.config.js (still not quite where we’re at with webpack-manifest… close.
We’ll notice that output.filename is part of the main config.
I validated this by adding console.log("webpack env", environment) to ./config/webpack/development.js and verifying that, apart from output of virtual-object names, :outputis indeed on the base config object.

SO (THE ANSWER) : edit ./config/webpack/development.js and add : config.output.filename = "js/[name]-[hash].js".

// ./config/webpack/developer.js - at least for my app

process.env.NODE_ENV = process.env.NODE_ENV || 'development'

const environment = require('./environment')

const config = environment.toWebpackConfig();
config.devServer = {
  contentBase: '.',
  host: "localhost",
  port: 3035,
  publicPath: 'http://localhost:3035/',
  historyApiFallback: true,
  proxy: {
    '/packs': { // string to look for proxying requests to api
      target: 'http://localhost:3035', // Path of your rails api server
    },
  },
}
config.output.filename = "js/[name]-[hash].js"

module.exports = config;

Enjoy!

Building an App – EKG

In this series, I’ll build an app in step-by-step posts that will produce an EKG (heart monitor) display.

The inspiration is the Phillips IntelliVue MP50 (found at my local hospital):

Tools we’ll use

Pretty much the whole point of this series… to learn some new tools and techniques:

  • Rail 6 – coming from a Rails 4/5 background, I’ll point out specifically “new to me” details.
  • SvelteJS – both introductory how-to and deep-dive into charting and real-time data streams.
  • Real-time data streams – although our sample data comes in CSV form, we’ll build some benchtesting harness to present this data to our front-end in “real-time”

Assumptions I’ll make

This tutorial makes many assumptions about you, the reader. Hopefully you can find what you need in the EKG – Resources page.

  • You know what Terminal is (or Cmd and PowerShell). You know what $ means in script examples
  • You know Ruby, and maybe Rails (not necessarily version 6)
  • You know some basic database operations, at least enough to understand Sqlite db

Project Details

I’ll be working through the following details over the series:

  • EKG sample data / downloads
  • Streaming real-time data to client (websockets)
  • SvelteJS
  • ChartJS (as a SvelteJS component)
  • ChartJS real-time update
  • Display layout
  • Automated downloads of sample data (web scraping the EKG sample-data site)
  • Creating a desktop app (ElectronJs + SvelteJS)
  • “VCR” controls over display – a design addition leveraging our desktop/mouse/keyboard oriented implementation

Let’s get started!

Brown Shoes Introduction

I will be writing about lessons-learned as I move through
the implementation of Shoes on Jruby.. known as Brown Shoes.

Repo – What’s what where

The Brown Shoes Repo is at : https://github.com/shoes/shoes/tree/brown_shoes – a branch on Shoooes Github project.

Right now there are two parallel implementations within
the brown_shoes branch.

At ./lib/shoes is the Eclipse SWT Library implementation.
This is using the expected event-loop main-display and
native SWT widgets.

At ./lib/brown_shoes is the Java/Swing implementation.
JFrame, JPanel, and a bit of AWT as necessary.

There are some issues found on the Pivotal Tracker for
Brown Shoes https://www.pivotaltracker.com/projects/444909

We need your help!

There are details about running SWT or Swing apps that
completely befuddle the newbie in this Jruby/Shoes
business. (namely.. ME!)

If you are a seasoned Jruby, Java/SWT, Java/Swing… or
maybe just JAVA developer, and have interest and a few
hours to spare, your expertise would be GREATLY
appreciated.

Who’s up for a fun challenge that will help Kids learn
Ruby – Hackety Hack runs on … Shoooes!

Pros & Cons – Rails vs. .NET Study

I’m debating between moving my career in one of two ways :

Rails

Study ruby on rails, leave Microsoft development, move my career in a new direction. I feel immediate happiness in this endeavor.

Pros

  • Test-driven development “baked in” to the development software
  • Installation and environment setup is free. No extra computer is required.
  • Ruby language contains “best-practices” of multiple languages and is “modern”. Ruby applies “LOLA” (Law of least astonishment), which makes it easier to apply “best-practices” to written code.
  • Community is VERY robust. Meetings are regular. IRC and listservs have heavy message traffic
  • My current skills apply to Ruby/Rails, even when from a different language/framework (IE Microsoft)
  • Best practices of Ruby/Rails align with current software-development industry research on best way to structure project management, design software, and build maintainable large-scale web systems.
  • By writing code in a system that aligns with best practices, I feel like I’m doing “the right thing” when I’m writing software.

Cons

  • Job Market is “currently” limited.
  • I need time to develop the skills/experience to support current income
  • Achieving experience appears to be a catch-22

.NET

Study Microsoft Certified Professional Developer (MCPD) / .NET 2.0. Give in to “the state”, admit that a governmentally structured certification machine also has a thriving job market. Join a Microsoft Consulting Firm full time and be a valuable contributor to their technologies.

Pros

  • Easy Job Market
  • I have valued skills (according to last job-seeking process)

Cons

  • Cost of Entry (Need new computer ($1000) + Software + Certification Testing $)
  • I don’t agree with Microsoft attitude toward developer community
  • I don’t agree with Microsoft attitude toward open-source / linux
  • Developer community is not robust (Few user group meetings in Chi, Forums/Elists don’t answer questions)
  • Microsoft web-development software (ASP.NET 2.0) does not support test-driven development
  • Microsoft development software is often confusing to read and confusing to use. Microsoft does not apply “LOLA” (Law of least astonishment).

Updated: 20 June 2007 12:35:00. This rounds out the pro/con list to more clearly present my perspective on what direction to take my career.

Sexy is only Skin Deep in Software

So I just watched the “5 minute video” by Iron Designer for .NET

Very sexy. Very very sexy.

As an MSDN subscriber (thanks to my corporate sponsors employers) and MCP (SQL Designer test or something, I’ve forgotten), this is very enticing…

AND .NET has failed me in several situations where I was trying to do something “outside the box”.

How does Ruby on Rails compare to this ?

Well the 10 minute video is almost a religious experience to many. AND Ruby and Rails DOES NOT fail us in situations where we wish to go “outside the box” in order to accomplish something.

That is all

Coverage (rcov 0.5.0.1) in Ruby on Rails 1.1.2

rcov 0.5.0.1: code coverage for Ruby released by Mauricio Fernandez contains all that is needed to produce code-coverage reporting in Rails.

Requirements

Ruby 1.8.4 (especially on Win32 requires updated libraries.)
Rails 1.1.2

Classes

There is only one file to add to your current rails app: lib/tasks/coverage.rake

require 'rcov/rcovtask'

namespace :test do
  Rcov::RcovTask.new do |t|
    t.libs << “test”
    t.test_files = FileList['test/unit/*.rb', 'test/functional/*.rb']
    t.output_dir = 'test/coverage'
    t.verbose = true
  end
end

Rake -T

Here’s the new tasks with rake -T :

(in C:/radrailsworkspace/pimki/trunk)
[... snip standard tasks ...]
rake test:clobber_rcov         # Remove rcov products for rcov
rake test:rcov                 # Analyze code coverage with tests
[...]

The default taskname for the RcovTask instance is ‘rcov’. Rcov automatically creates the ‘clobber_’ task that is basically a rm_rf on the RcovTask#output_dir.

Cover it

Run rake test:rcov and see how much of your code is really tested!!

Report Coverage

The end of your rake run will contain a pretty-print text report of the rcov. Also, you can navigate to ./test/coverage/index.html to see the graphic report. See the docs for more info.

Single Fixtures declaration for Selenium on Rails

When testing out a complex website, replicating the |open|/selenium/setup?fixtures=x| line would be painful!

So, Add a const at the beginning of the setup_controller in Selenium Plugin at
./vendor/plugins/selenium_on_rails/lib/controllers/selenium_controller.rb:

MY_FIXTURES = “table_a, table_b, table_c”

Also alter #setup as so :

def setup
    unless params.has_key? :keep_session
      reset_session
      @session_wiped = true
    end
    if params[:fixtures] == “all“
      fixtures = PM_FIXTURES
    end
    fixtures ||= params[:fixtures].to_s
    @loaded_fixtures = load_fixtures fixtures
    render :file => view_path('setup.rhtml'), :layout => layout_path
  end

New lines are 6-9, and the change on 10 from referencing params[] to the local var fixtures.

Then, use this in the selenese script :

|open|/selenium/setup?fixtures=all|

Isn’t that beautiful!??

Now I don’t have to endure copy-paste-age-break hell on my fixtures configuration.

Ahhh, Ruby is so nice!

1 – Strategy Pattern

The Strategy Pattern really resolves to “composition” in practice. This OO technique says to take components that could change at runtime and encapsulate them in their own objects. The master-object is then “composed” of instances of the dependent clasess.

Example:

class Duck
  def fly
    puts ‘Flap Flap’
  end

  def quack
    puts ‘Quack!’
  end
end

d = <span class="constant">Duck.new
d.flap
d.quack

Produces:

Flap Flap
Quack!

So now handle the en-user request to have ducks with different flap :

class FlapWings
  def fly
    puts ‘Flap Flap’
  end
end

class FlapSoaring
  def fly
    puts ‘Soaring in the wind’
  end
end

class Duck
  def initialize (flapInstance)
    @flapDelegate = flapInstance
  end
  def changeFlap(flapInstance)
    @flapDelegate = flapInstance
  end
  def fly
    @flapDelegate.fly
  end

  def quack
    puts ‘Quack!’
  end
end

mallard = Duck.new(FlapWings.new)
mallard.fly
mallard.quack
mallard.changeFlap(FlapSoaring.new)
mallard.fly

Now produces :

Flap Flap
Quack!
Soaring in the wind

This example looks trivial. The technique is powerful. Behold that in Java/C#, this requires a lot of effort including Inheritance and Interfaces.

Nice that Ruby allows this run-time change through duck-typing!!

Use AJAX for onchange of a SELECT box

Here’s how to use AJAX from the onchange event of the SELECT element :

I used an extra ERB step in my view in order to reduce chaos being created by double quotes. This example actually triggers two AJAX calls on the event to update different targets (two cascaded SELECTs).

 :model_select,
                    :url =&gt; { :action =&gt; :ajax_list_model_select },
                    :with=&gt; " 'project_id='+value") + ";" +
                 remote_function(:update =&gt; :category_select,
                    :url =&gt; { :action =&gt; :ajax_list_category_select },
                    :with=&gt; " 'project_id='+value")
                 %&gt;

 onchange_ajax } ) %&gt;

The result has the SELECT element with onchange=”new Ajax.Updater…”

Joy!