enric ribas on Ruby, Javascript, Rails, and the rest of the things in life that bug me.

React Actions -> Rails Commands

This is a followup to my previous post about React with a Flux-y store

Sidenote: I am looking seriously into Redux, but haven't made the move yet.

One thing I really enjoy is using freezer to directly modify the local data and having freezer update itself and therefore all the views.

Another thing I noticed is that the when you need to persist the changes to the server, Reflux actions are a very nice way to define the change. However, it is a pain to have to define an action, create an endpoint, deal with the returned data, etc., each time you add a new action.

While React is the new-hotness on the client-side, for me, at least, EventSourcing and CQRS are the new-hotness (ok, not new but growing in popularity) for the server side. On reading about this, I have noticed a strong similarity between "Commands" on the server and "Actions" on the client side.

So, I was thinking, why not create a single endpoint on the server that accepts "actions" and converts to server "commands"?

Sidenote:

This is orthogonal to using something like GraphQL. It doesn't exclude or replace its use but it doesn't require it either. Adding GraphQL to this process would be quite easy.

If you look at the example from my previous post...

// recipe.jsx

var Actions = require('actions');

 ...

  onClick: function (e) {
    this.props.name.set("New Recipe Name");
    // current way of calling store
    Actions.changeName(this.props.id, "New Recipe Name");
  }
}

module.exports = Recipe;  

Previously, this would have made a call to a store method which then calls an explicit endpoint on the server specifically for changing the name, and then the store would have dealt with the data returned. This works but is time-consuming and repetitive.

You can now imagine that the Actions store could simply call an endpoint on the server with the method name and the data and all other "actions" would also hit the same endpoint. For simplicity, you might want to change the Actions call...

  onClick: function (e) {
    Actions.command("changeName", {id: this.props.id, name: "New Recipe Name");
  }

The actions store would simply delegate to the endpoint.

  ...

  onCommand: function (command, attrs) {
    // fetch polyfill
    fetch('/commands/' + command, attrs);
  }

  ...

Once this is done, adding a new action would not require any changes to the store.

On the server side (Rails) you would need a CommandController

class CommandsController < ApplicationController  
  def create
    if CommandRunner.run(command, params[:body])
      render json: {}, status: :ok #for now
    else
      render json: {
        error: ["something went wrong"]
      }, status: 422
    end
  end

  private

  def command
    params[:command]
  end
end  

If we wanted to get really fancy here, we could use something like RailsDisco for full event sourcing or use CommandObjects or use our own implementation for now.

class CommandRunner  
  def self.run(command, params)
    runner = runners[command]
    runner.new(params).run
  end

  private

  def self.runners
    {
      changeName: NameChanger,
      addIngredient: IngredientAdder,
    }.with_indifferent_access
  end

  class Runner < Struct.new(:params)
  end

  # These would probably be in a different file
  class NameChanger < Runner
    def run
      Recipe.find ...
      etc ....
    end
  end

  class IngredientAdder < Runner
    def run
      Recipe.find... 
      etc ...
    end
  end
end  

SideNote: CommandObject by Josh Adams, a nicer implementation of Command Objects

class StudentTransferCommandsController < LoggedInController  
  def create
    transfer = StudentTransferCommand.new(params[:student_transfer_command])
    transfer.student_id = current_person.id
    transfer.on_success = method(:on_success)
    transfer.on_failure = method(:on_failure)
    transfer.execute!
  end

  def on_success
    flash[:success] = "Transfer successful."
    redirect_to bank_path
  end

  def on_failure
    flash[:error] = "Invalid transfer."
    redirect_to bank_path
  end
end  

So we still have to deal with the response data from the server. What if we try to save but it fails for some reason?

Ideally, we would use something like Pusher to post back the data as it changes, but that's a topic for another post. For now, we can have the store listen to the response with a callback.

  ... more code

  onCommand: function (command, attrs) {
    // using polyfill fetch
    fetch('/commands/' + command, attrs)
      .then(function(response) {
        return response.json();
      }).then(function(json) {
        // Because we're using freezer, this will trigger Reflux to update
        // This also implies that we are updating the entire tree of data
        // which is not efficient. 
        // Ideally we would only replace the portion of tree that changed.
        this.store.get().set(json);
      }).catch(function(ex) {
        console.log('deal with me!', ex);
      })
    ;
  }

  ... more code

The controller would of course have to return some data

class CommandsController < ApplicationController  
  def create
    if id = CommandRunner.run(command, params[:body])
      # all_data is pseudo-code of course
      render json: all_data(id), status: :ok

      ...
end  

We are making the assumption that the data returned from the server completely replaces the data on the client-side. While this might work for smaller apps, this is not great. We probably should return a subset of the changed data and replace/merge it with our existing data. We'll leave that for another day as well.

Conclusion

So I think that by updating the data on the frontend with freezer and calling a "command" on the front-end, we have greatly simplified the front-end. Now the backend gets a command from the front-end (aka "action") and it returns data after updating. Essentially, the store shouldn't have to do much at all, just delegate to the server.

I think this is a nice clean way of dealing with changes. What do you think?

An idea for React with a Flux-y store

Using Reflux and Freezer as data store

React is an amazing advancement in web development. It creates an implementation that is simple to create, reuse, and understand. It has strong opinions about front-end rendering but it has no opinion about how data is stored, manipulated and then persisted. I think that's a good thing. There are a lot of different use cases and opinions about the best way to handle data and it really shouldn't be part of React's responsibilities.

Flux was introduced shortly after React by Facebook as a pattern to try and solve this problem. There seems to be no major consensus on the best approach however. Flux Comparison is a comparison of many of the options currently available. Yet even that list is missing some options, like Microcosm, so there are lots to choose from.

Personally, I find a combination of an immutable data structure and a simple implementation of Flux to be the best. First let's start with the immutable data store.

While there are a lot of more popular libraries for Flux and for immutability. I personally like freezer.js and Reflux because... well... they are easy enough for me to understand.

If you find you need to switch, it much easier to start with these options and swap out later than to not use some form of flux or immutability, because the concepts will be the same.

Immutable Data

Freezer:
  • uses a simple api
  • doesn't require getters for accessing data
  • has events when someone tries to update the data structure.

Their github page has some great examples about how to use freezer but let's go directly to a practical example. I like to work with just one store (per route). Each route gets a store and a list of possible actions. All the data for that route is contained in the store passed to the uppermost component which I call a 'Container'.

Before we get into Reflux, let's just use immutability to update our components. We'll just use the Store but no Actions from Reflux, but this could be done just as easily without a Reflux Store.

//store.js
var Freezer = require('freezer-js');

var Store = Reflux.createStore({  
  defaultData: {
    user:    undefined,
    recipes: []
  },

  init: function () {
    this.store = new Freezer(this.defaultData);

    this.store.on('update', function (newData) {
      // NOTE: Called every time data structure is modified

      // checks to see if data is actually changed
      if (this.data != newData) {
        this.data = this.store.get();
      }

      this.trigger(this.data);
    }.bind(this));
  }
});

module.exports = Store;

So this.data contains an immutable version of the data from the store this.store retrieved with the get() command. It will be this data that is passed into the 'Container' which will then pass a subset of that data into each component as props.

So how do we use that Store?

// app.js
var React         = require('react');  
var Reflux        = require('reflux');

var Store         = require('store');  
var SomeComponent = require('components/some');

var App = React.createClass({  
  mixins: [Reflux.connect(Store, "data")],

  getInitialState: function() {
    return { data: {} };
  },

  render: function () {
    return (
      <div>
        <SomeComponent {...this.state.data.recipes} />
      </div>
    );
  }
});

module.exports = App;

So how is this.state.data.recipes getting its data? That's a bit of magic from Reflux. Again you could do this without Reflux but when we add Actions you will see how it's easier to keep with Reflux.

The magic is the Reflux.connect call which will update this.state.data (or whatever from the second argument) every time the Store calls a trigger method (in the store.js) with the data passed into the trigger method, in our case a copy of the immutable data from this.data.

You can pass all of the data or only part of it to the sub-component. In our case, we are passing a subset in this.state.data.recipes but that will still be an immutable copy. Any changes to this data will result in a call to the this.store.on('update', ... method in our store. And therein lies the magic. Any change to any part of the data results in a change to the entire data structure updating everything at once.

If we take a look at a hypothetical version of a Recipe component further down the chain that gets one recipe passed as a prop...

// recipe.jsx

var React   = require('react');

var Recipe = React.createClass({  
  render: function () {
    return (
      <div>
        <h1>{this.props.name}</h1>

        <p>{this.props.instructions}</p>

        ...more code
      </div>
    );
  },
 ...more code

  onClick: function (e) {
    // NOTE this.props.name is an immutable object
    this.props.name.set("New Recipe Name");
  }
}

module.exports = Recipe;  

So if we wanted to change the name of the recipe, the set command would cause the store.js 's `store.on('update', ... to run its code getting a new fresh immutable copy of the data from this.store and then passing that down again through trigger

This makes it incredibly easy to ensure that all the components that rely on this data to be updated at once, once any of the data changes. For example, if you had a different section of the page that listed all the names of all the recipes, as soon as you changed the name in this component the name data would get fired and you would get new fresh data. React would be smart enough to only update the things that are changed. And because you are using an immutable structure, you can use shouldComponentUpdate to check javascript object equality and render only if the data changed.

Reflux

Persisting Data

So we can now make changes to the actual data structure and it is automatically reflected on our frontend. But what if the name is already taken? Or if we refresh the page? What if the rules for the data prevent that name change?

We need some more structure in order to persist. This is where the Reflux/Actions pattern comes in. If we modify our onClick method above...

```
// recipe.jsx

var Actions = require('actions');

 ...more code

  onClick: function (e) {
    // NOTE this.props.name is still an immutable object
    this.props.name.set("New Recipe Name");
    Actions.changeName(this.props.id, "New Recipe Name");
  }
}

module.exports = Recipe;  

So where does changeName come from? Let's look at the actions.js file.

//actions.js

var Reflux = require('reflux');

module.exports = Reflux.createActions([  
  "changeName"
]);

That's it. That's how you define an action in reflux. Ok, big deal what does that do? Let's return to the store.js and see what changes we need to make.

// store.js

var Reflux  = require('reflux');  
var Freezer = require('freezer-js');

var Actions = require('actions');

var Store   = Reflux.createStore({  
  defaultData: {
    user:    undefined,
    recipes: []
  },

  listenables: Actions,
  init: function () {
    this.store = new Freezer(this.defaultData);

    this.store.on('update', function (newData) {
      // NOTE: Called every time data structure is modified

      // checks to see if data is actually changed
      if (this.data != newData) {
        this.data = this.store.get();
      }

      this.trigger(this.data);
    }.bind(this));
  },

  onChangeName: function (recipe_id, newName) {
    // pseudocode alert
    request.post(...., function (dataFromServer) {
      this.data.set(dataFromServer);
    }).bind(this);    
  }
});

module.exports = Store;  

I don't love magic and would prefer more explicit connection from the actions to the store, BUT, if you call an action changeName it will the onChangeName function on the store, assuming your store is listening to the Action file, which we do with the listenables method.

In our, onChangeName function, we can do whatever we want. We can client-side validate the data, we can make server requests, etc. Once the data comes back from the server it either completely replaces the data in this.data or merges in the parts that you are replacing. It's up to you. Because we are modifying the immutable data again with the set command, the on('update') will "repush" the data back down to the Container.

Conclusion

It seems we have a solution that is

  • easy to understand
  • easy to modify
  • easy to test
  • performant
  • ensures data consistency

What do you think? Is this easy to understand? Are there some problems with this approach? Is there a better way?

Development Tools & Gems

This will probably be out of date by the time you read this. :)

In the Ruby on Rails community, we are very lucky. There are so many tools available for us to use that the problem often is finding out which ones are worth using and which ones aren't worth the time to install.

Some of these things, my team will agree on and others they simply think I'm crazy. But these are the basic tools that I like to use when developing Ruby on Rails applications.

SHELL STUFF

iTerm2

I love iTerm2. It's a replacement for the standard Mac terminal but has a few nice features. The killer feature for me is split panes. Using a large screen like the iMac 27"s we have it's great to have iTerm2 fullscreened and then split the screen into vertical CMD-D and horizontal CMD-SHIFT-D splits. I like to use one pane for vim, one for rails console, one for bash, etc. Use CMD-W to close a pane. Right-clicking will give you an option to move a pane around which is actually fun #iamnerd.

One press of CMD-Enter and just that pane gets fullscreened (especially useful when iTerm2 itself is not running as fullscreen). Press CMD-Enter again to return to the previous state.

Unfortunately, iTerm2 to my liking isn't set up properly when you first install it. You have to customize a few things. My first customization is setting up CMD-ALT-ENTER to always bring up or hide the terminal. No more ALT-TABbing around just press it and it's there. Seems pointless but will save you a ton of time in the long run.

I also set up keys for moving from window to window. I use CMD-[arrows] for switching from window to window. You can still use CMD-SHIFT [|] (left and right brackets) but it's pretty weird because it tracks which windows were opened first and not the order on the screen which is not intuitive.

Mostly importantly, you need to set up new windows to open in the folder of the previous window. Not sure why that's not the default but whatever... Then you can open a new split it's already in the correct folder. This makes it really quick to be in the middle of a command, make a new pane, run a new command (or queue a new command for later) and then close it when it's done.

We have different apps that we run, so I use multiple tabs for that. One project, one tab. Then I split panes for a rails console, an rspec screen, etc. CMD-1, CMD-2 to switch between projects.

VIM bindings

I use vim bindings for my command line editing, because otherwise, well you know what it's like to edit a long command line with just arrow keys and backspace. It basically sucks...
Whenever you want to edit your command line you press ESC (which I have mapped to the CAPSLOCK key because seriously what's the f'ing point of CAPSLOCK? I use PCKeyboardHack for mac for that.)
run..
set -o vi
in your .bashrc file and get awesome vi-iness on your command line.

Zeus

Rails is great but as your application grows, it takes longer and longer to start up. This gem makes it quite annoying run tests, generator, console, etc. Zeus boots up your environment once and stays loaded and ready for your commands. It's even smart enough to reload itself (sometimes) when you change certain files. It's Mountain Lion only, but if you have it, you should use Zeus.

We used to use spork but we had problems with it and it doesn't work with generate or console, or server, just tests. It also doesn't restart itself with files changes. Basically Zeus is better.

To run commands with Zeus, simply type 'zeus' instead of rails like 'zeus generate ...' or 'zeus server' or 'zeus rspec ...', etc. With Rake commands, type 'zeus rake command' like 'zeus rake routes'.

Hitch

Update: We now use git pair

We use the hitch gem at work because we pair program 100% of the time (except for devOps stuff). This gem hijacks git reporting to automatically assign both people working on code to show up as authors. If you pair program, you should use this.

Aliases

Ok, I get made fun of here at work, but I love my aliases. If I have type something more than three times, it becomes an alias. Or if it's hard to remember after just one time. They are stored in dotfiles in my github account. Here are some examples of the less common ones...

migrate = bundle exec rake db:migrate db:test:prepare  # because I always forget to test prepare.

rs = zeus rspec -f d  
gs = git status --short  
glg = git log --color --decorate --oneline --graph  
gpd = git pull && rspec spec && git push origin development # can't push without running tests  
gc = git commit -m # you can always add -a after your comment  

and my favourite and most perhaps the important, and the one everyone makes the most fun of me for ...

ali = vi ~/.bash_aliases # lets you quickly add a new alias.  

GEMFILE STUFF

pry (and pry-remote)

I have no idea how I programmed before pry. Pry lets you stop execution of code at any point by simply typing binding.pry. Then you get a REPL at the breakpoint in your server terminal. From here you can type commands, check variables, etc. When you're ready to continue type 'exit' or CTRL-D.

Unfortunately we now use POW so you have to use pry-remote which doesn't always work. To use pry-remote type binding.remote_pry in the code and then in a bash terminal enter 'pry-remote'.

xray

I just recently discovered this gem and instantly fell in love. In chrome only, you can press CMD-SHFT-X and it will display a series of boxes around each of elements on the screen with the view that rendered that section. Clicking on one of those boxes will automatically open that file in Sublime. Amazing! It even works with backbone views!

better_errors

Not a huge deal, but this gem creates nicer crash screens which open up a REPL at the point of the error which is really nice for debugging. I don't use often but I'm glad when I have it.

Actually now that we use POW and pry sometimes doesn't work, you can explicitly raise an error and get a REPL which is great!

EDITOR STUFF

VIM

Personally, I love VIM. VIM is pretty crappy out of the box for Rails development, however, and setting it up is painful. I have set up vimforrails.com with more information about setting it up.

  • A brief list of my favourite bundles, packages (whatever they are called) is listed here...
  • vim-powerline
  • ctrlp
  • surround
  • rails
  • ack
  • and many many more...

There are also a lot of other basic settings that I feel are a must for productive Rails development which is too lengthy and may deserve its own post. Feel free to check it out at my github repo.

Sublime

Once sublime is set up the way I like it, I am almost as happy using it over VIM. Sublime is truly amazing and blazingly fast for GUI editor. The community and packages are also amazing. If you are using any other GUI-based editor, I think you should switch. It has an unlimited trial period with nagging if you're not a professional developer or simply want to test it out.

There are many many packages available but the ones I find most valuable are...

  • syntax specific ones, like Rails, RSpec, SCSS, HAML, etc. which include snippets and highlighting
  • SublimeAllAutocomplete - autocomplete across all files.
  • ERB Insert and Toggle Commands - it's awkward to type so this helps
  • Git - for git blame, commits, etc., within sublime I only use blame inside Sublime but it's nice
  • ColorPicker - for choosing CSS colours, very useful

Again, my setups are available on my github and everyone is welcome to use them. Feel free to fork and customize.

I also like Vintage (vi-like) mode in Sublime, though it's annoying to use with a pair because they press ESCAPE and get annoyed. And when I work alone I use VIM anyway, so Vintage is something I will probably remove soon from Sublime. Also it doesn't support everything in vim so it can be frustrating.

Well, that's about all I can think of off the top of my head, good luck and comment about useful tools you use.

ActiveRecord Callbacks == Evil?

I want to start this blog post, the same way I start all my posts, explaining that I really do love Ruby On Rails. My blog posts are critical of Rails because I love it and want it to improve so I don't have to one day switch to Django or (yikes) some PHP framework.

When I was interviewing for my current job, I was asked what things I would change about Rails and Ruby and that inspired me to think about it more and more. So I thought I'd start a new series of blog posts on a few of my least favourite Rails features; things I would love to see gone from Rails 5.

These things that just have "code smell" to me in and although I'm not sure I will have a better solution, it might be fun to explore.

One thing that constantly bothers me in our code base at Influitive is model persistence callbacks, especially conditional callbacks. I wrote about this and validation callbacks once before.

Here is an example from just one of our models.

challenge.rb
## lots more code before

after_create :set_reference_defaults, if: "reference_request?"  
before_validation :check_prospect  
before_save       :update_activities # This should come before update_flags to make sure confirmation_required is cleared for deleted stages  
before_save       :update_flags, :set_simple  
before_destroy    :check_deletable?  
before_save       :update_listeners  
before_create     { build_statistic unless statistic }

## lots of code after.

Why is this so bad?

Well for one thing, the ordering is confusing. The aftercreate comes first yet happens last, so the ordering in the code doesn't matter. Or does it? There are three beforesave(s) so what order do they happen in? The two on line 6, which one happens first? Are you sure?

What about observers? When do they happen in relation to these callbacks? What about an aftersave vs aftercreate, do you know which happens first? Will the next programmer who looks at this code?

Also, the logic for whether something is called should be contained within the object that is doing that action. For example, if a reference request should only get defaults set if it's a referencerequest?, then that method should decide that. If we only want to build a statistic on first creation and only if it doesn't already exist, then put that logic in one place, where it belongs, in the buildstatistic method. I don't want to have to check two places to find the logic involved.

However, the biggest problem with this code, is what is required from Rails in order to do this kind of magic. (see side note).

SIDE NOTE:

The code in Rails to implement callbacks is pretty ridiculous. Some crazy compromises had to made to make this "magic" work. 

We don't often think about the time needed to maintain this type of code, but it is a huge cost that make any changes very difficult especially for people new to the language or framework. 

If we could remove this code and use standard Ruby processes, we would have much less code to maintain, bugs to track down, and a lot less stress in general.

Checkout ActiveSupport::Callbacks for some fun reading. If you understand this code, write a blog post and explain it to me. :)  

So what can we do about it?

I'm not sure really, but one thing we could do is create a service class that builds a valid challenge model based on the the params given. It doesn't really seem like the job of the challenge model to update activities or flags. Its job should be to persist itself to the database. That's it.

Ignoring that for now, a simple thing we could do is use inheritance. Since we are inheriting from ActiveRecord::Base, why not overwrite the "save" method (technically createorupdate is better to use) to run our actions first? It's simple, it's standard Ruby and everyone understands it. There is no magic, no disadvantages as far as I can see, and reduces framework code.

## lots more code before

def create_or_update  
  update_activities
  update_flags
  set_simple
  build_statistic # check for existing statistic and if new_record? in the build method
  super # this saves!
  set_reference_defaults # should check for existing defaults
end  

As a side note: if the save method is doing this much work, there should probably be a service class builder. imho

Thanks... Opinions?

Daily Sync-Up

In my two years at Influitive, we have grown incredibly quickly from 5 people to now at almost 40. At times, we have grown quicker than the business practices and processes we had in place and had to adapt solutions quickly sometimes ending in less than ideal results. We implemented enterprise solutions when we were too small and SOHO solutions when we were too large. We have moved fast and broken things; such are the growing pains of a startup.

I believe that proper business practices that achieve a balance of simplicity while allowing for growth are a key factor in the success of any business and I would value it over a proper business plan. I think it's important to make a lot of mistakes and learn what works and what doesn't. You must be willing to drop something quickly when it isn't working and not be afraid to try new things. One thing we have found very helpful and quite enjoyable has been the daily sync-up meeting.

A Daily Synch-up meeting is an opportunity for the entire company to get together once a day and get a progress update on what everyone else is doing. It's a quick meeting, ideally no more than 9 minutes. Why 9 minutes? No one knows, it's like the 6 minute workout.

This meeting is heavily inspired from the Agile movement's stand-up meeting with some changes. For us, it involves a few important stages at which any one is allowed to talk.

  • Important company wide news
  • Introductions. If anyone is visiting the company or interviewing.
  • New sales leads and opportunities
  • Blockages. Things that are stopping you from doing their work.
  • Insights. Something you've learned that might help others.
  • Today's accomplishments. A 3 second statement of what you will accomplish today.
  • and my favourite... The department spotlight. A three (3) minute presentation from someone from one department describing something that is of interest to everyone in the company.

Recently, it was my turn from software development to give my presentation. I realized from some questions I'd had from others in the company that outside of dev, no one knew what pair programming really meant and why we were doing it. So I decided that my presentation would be on pair programming. slides here.

It was a very short presentation with some humour (in theory) and not much detail, and that is the point of these presentations, they are a light-hearted, very quick overview of a concept that might be obvious to your department that others might be interested in.

We have found that the sync-up meeting keeps us informed about the rest of the company, the company's mission, and keeps us feeling like part of the connected whole. It is also a good time to learn what others need and how you can help them succeed.