I'm a Floridian web engineer who planted his roots in Paris. Some of my favorite past-times are analyzing and optimizing development processes, building solid APIs, mentoring junior devs, and long walks on the beach.

Control your points of modification 10-22-2017

I was reviewing a controller the other day and I came across a piece of code in rails that modified incoming params in multiple spots. What follows is a contrived example of a solution implemented to handle a date that had to have a different format on the front-end and so had to be parsed according to the user's chosen date format.


class ShoesController < AdminController

    def update
        parse_and_format_date
        if shoe.update(shoe_params)
            redirect_to shoe_show_path
        else
            redirect_to shoe_edit_path
        end        
    end

    def shoe_params
        params.require(:shoe).permit(:buy_date, :title, :id)
    end

    def parse_and_format_date
        params[:shoe][:buy_date] = DateTime.strptime(params[:shoe][:buy_date], user.date_format)
    end
end

The problem I had with this controller is that we are modifying the params in multiple places, first in parse_and_format_dateand then in shoe_params. Also, we aren't particularly clear about it. Without looking into parse_and_format_date it is not immediately clear that it modifies the params.

For me, this is a major no-no but I had trouble articulating why. The only real answer that I could come up with was that debugging later I would have to ask myself where the changes to the params was happening, and the more places I put the changes, the more places I would have to hunt down to ensure that I was not making a bug. Also, parse_and_format_date does not clearly show that it updates the params object. In this file, it's not a big deal, but the bigger the file, the worse it gets, and if you add some concerns the next person to read this code will start scratching their head.

Source of truth

The shoe_params method should appear to be frozen in time. I should not be able to call it in multiple different places in my update method and get a different result. What's more is that the manipulations being done to the params variable should not be so heavy that they can't be done repeatedly if necessary. Also, strong parameters are not usually called multiple times in an action, so it's not crazy to think that it can contain these transforms.

If we made parse_and_format_date idempotent then we could do something like this:

def shoe_params
    params[:shoe][:buy_date] = parse_and_format_date
    params.require(:shoe).permit(:buy_date, :title, :id)
end

def parse_and_format_date
    @parsed_date ||= DateTime.strptime(params[:shoe][:buy_date], user.date_format)
end

In that situation, we would always now what shoe_params contains and it would be clear at any point of any action we call in our controller.

Styling Things in a Component World 03-28-2017

As I slowly work towards using react into some of my projects, my first real question was how to style my components. There have been quite a few evolutions of CSS in the past few years. We've gone from straight CSS to SASS or Less to give better maintainability, Bootstrap to deal with the volitile nature and make our pages a little more standarized. The list goes on but all of these solutions are to make the fundamental problems of CSS less bothersome.

css is awesome

Component centric CSS?

Component centric CSS is the concept of attaching your css to a react component. One of the main benefits that comes from a component driven front-end is the encapsulation that it engenders. No longer does the developer worry about merging multiple small pieces randomly throughout a codebase into a single structure. Instead, each component has its own style attributes. This component has its own error handling, it has its own event listening and it doesn't bother too much with what is going on in other components except when parameters are passed. Each component is the master of its own domain. The main qualm with traditional css is that it is essentially all defined globals. While there have been some attempts to solve this, notably with BEM it feels like a hack to codify your class names to handle a lack of namespacing in CSS.

Applying a component mentality to CSS

I know what you are thinking, "It is called Cascading Style Sheets for a reason". There are a few different approaches available, so bear with me. Here are a few solutions out there.

  • Hard coding: Apply styles directly to elements via the style attribute
  • Styled Components which allows for use of CSS but applied directly to components
  • CSS-IN-JS: which treats your CSS as JavaScript and applies it to components directly.

The Old standard

I am currently using react-bootstrap in my project, and that works exactly how I would expect. There is a defined CSS file included in the site. The react portion handles only the setting of classes and other things which affect the style defined in the included CSS file. The points in using this are:

  • There is potential for clobbering a namespace but the classes are well-defined so it isn't probable
  • Having to debug styles based off of specificity(Why isn't my style showing up?)
  • Having to manage the the structure of the files
  • It is an old evil, but a well-known one. There aren't a lot of surprises in store.

Full disclosure, I am using this as a base and then using CSS-IN-JS to set the rest of my styles.

A New Approach: CSS-IN-JS

Some people have been jumping on the bandwagon for writing inline styles. There is another option though which builds CSS classes dynamically, directly into your components. You may be saying, "Inline Styles?! The warning flags are in the air!", and I will admit that I was skeptical at first. Styles are defined directly on the elements, though they are not truly "inline". This goes counter to everything most of us have learned when getting started with web development. But since, the un-examined belief isn't worth having, lets take a moment to stop and think about why.

Putting CSS Styles directly on elements hurts re-usability.

I want to make styles for a button and be able to use those styles for every instance of said button. The approach to CSS-IN-JS, is to define a dynamic class at instantiation time of a component, from then on, that class is applied to the component. What is nice about this is that you can have multiple styles associated to a component, and then attach them at runtime. You aren't actually re-adding styles to each element.

A side-effect of this, is that you view your styles more as something attached to your components. So structurally it makes sense to keep them with your component. All of my files are located with the component that they style.

  /components
    /MyBadassComponent
      MyBadassComponent.jsx
      styles.jsx

Putting CSS styles directly on elements hurts caching

The styles are defined statically as part of your JavaScript project. So caching them and gzipping them is still part of the deal. The dynamic style building part comes after the page load as part of rendering components. As different components are generated, their styles are dynamically written to a style tag. I suppose that technically your code size doesn't bloat with inline-styles either in using react since the individual components are re-used.

Putting CSS styles directly on elements will essentially override everything else

While this is true for styles written directly to an element via the style attribute, but CSS-IN-JS works by generating classes. This means that if you want to use something like bootstrap, you can happily use their solutions with yours. You can also use other outside libraries and they won't be overridden directly by any styles you choose to use.

Just mix the thing with the thing

Since react is still all new and magical to me, I may do a follow-up article, "Why to never use CSS-IN-JS", it is possible that I will hate it after I've spent some time implementing it. But for now it's my chosen way forward. Here are a few resources for learning more about CSS-IN-JS:

STI Models and a Misconception of DRY 02-25-2017

One of the biggest problems in programming is how to handle and simplify the logic that shows up in your application. Logic which shows up uniformly throughout a class tends to be a smell which indicates the need to represent multiple different concepts. Here is an example of how this can manifest:

Example:

class ThingController < ApplicationController
  def create
    if creation_params[:kind] == 'First'
      First.create(creation_params)
    else
      Second.create(creation_params)
    end
  end

  private

  def creation_params
    params.require(:thing).permit!
  end
end

What's happened here is that we have two separate classes, here First and Second. If you are familiar with STI then you probably have seen this sort of thing often. The problem is that the objects share a data schema, but they will have potentially different views, potentially different validations and they will do potentially different things, ie they have different domains.

Keep it DRY

DRY

People often wrongly cite that they are staying DRY by merging two domains or by combining two functions. But the concept is actually not referring to code. The principal is referring to having a single representation knowledge or a single source. So an example of keeping code dry is to not have a constant show up in all of your view code.

.header
  %p Default circle size is 300 mm.
  .blurb
    Space remaining:
    %span = circle.size - 300

Instead you would store the size as a constant or a method in a class.

class Circle
  def self.max_size
    300
  end
end

.header
  %p= "Default circle size is #{Circle.max_size} mm."
  .blurb
    Space remaining:
    %span= circle.size - Circle.max_size

Manifestation of Excess Logic with STI:

If we look back to our original controller example, we see that there are two separate domains that are being handled by one single controller and that while the total amount of code is less(potentially), we haven't actually simplified our lives. As we add more subclasses to the STI model we will see an unhappy pattern emerge. Potentially we will have a case-statement to select our object and to have them do different things. We will have to define functions like this outside of our models that will then manage the models.

The solution is to not be afraid of having more files, not thinking that less code is necessarily more manageable. Treating the two models as separate resources will make maintenance easier from our routes to our views.

The problem with putting two separate models in the same controller is that there is a branch that starts in the route, and goes all the way to the view. The only argument that I have seen is that you can save on the amount of code you write by putting them in the same controller and giving them the same route. Doing so however makes all of the code associated more complicated as there is now a branch for every reference to the model. If there really is no divergent domain code, then there is no reason for STI. STI is not a way for you to treat two separate things as the same, it is a way for you to treat two things with the same data as different.

Tags: dry STI Rails

Exceptional code 01-22-2017

When I started programming, I never gave much thought to exceptions. I did not realize the benefit. If you write mainly interpreted scripts, they may seem like any other error that explodes during execution. Of course the difference, is that they are controlled explosions.

Some of the primary benefits are that they:

  • Allow you to expect some sort of known potential failure.
  • Allow you to know where the failure came from.
  • Allow you to fail gracefully.

The bad and the ugly

One of the worst things that I've seen is what follows:


def source
  begin
    risky_business
  rescue 
    nil
  end
end

The problem here, is that instead of handling failure, we just ignore it. There is no way to know what happens or why it happens. If risky_business normally returns nil, we may also think that function has passed when it really fails.

The next snippit is better, but still not without its problems.


def source
  raise "The source of all your problems"
end

def bad_exception_catcher
  begin
    source
  rescue Exception => e
    clean_up_the_stuffs
    raise e.message
  end
end

The problem here is a little more subtle. It is clear that we are taking advantage of being able to clean up problem code, however, there is one key problem. We are creating a new exception when we "raise e.message". This means that later in the logs, this call will be the source of the backtrace and not the original source function. If our source function is just one line, then there is no problem, but the more complicated that source function is, the more difficult it will be to pinpoint the problem.

A way to get around this problem, is to just reraise the original exception. In that way we will keep the original backtrace history.


def bad_exception_catcher
  begin
    source
  rescue Exception => e
    clean_up_the_stuffs
    raise e
  end
end

Testing

Typically, exceptions are something that you can and should test for. Also, if you are using ruby and something like rspec, exception testing is supported out of the box.


it "should raise error if user has no email" do
  user = OpenStruct.new(email: nil, name: 'A. Person', uid: 10244201)
  FbGraph2::User.stubs(:me).returns(user)
  expect { user = User.facebook_get_user('access_token') }.to raise_exception(
    LoginException, 'Please use an account with a valid email'
  )
end

In testing for specific exceptions, you can also assure that you don't get unexpected exceptions.

MongoDB Musings from a Beginner 08-06-2016

Counter Cache

If you are used to the way that SQL databases work, then you are also used to the implementation of a counter cache. In Rails it is a trivial implementation. Essentially, it will internally maintain a cache of the count of associated objects in a relation, this results in more data management but it avoids an extra query every time you need the count of associated rows.

In MongoDB, certain types of associations will get this functionality out of the box. With a HABTM and a many to many relationship, the counts will be stored by virtue of the type of associations. This is because there are no joins in Mongo, so the references to a document must be stored directly on that document. Therefore, you end up being able to do something like document.ref_ids.count.

No Joins

In Mongo, there are no joins, only more queries. This can be kind of annoying if you are used to doing more work directly on the database. This means that if you want to join two tables, you need at least two seperate queries. It also means that you need to think more seriously about where certain data needs to go. Should it be in it's own document or embedded in another? The upside, is that aggregations within a collection are extremely powerful.

N + 1 Fun

A quick note, if you are using something like ActiveRecord you can still easily avoid the N + 1 query problem. A call to include works more or less the same way, but of course it will be done with 2 queries instead of a join.

Schemaless Schema

People tend to think that the fact that MongoDB is schemaless means that you can just add new attributes or change attributes without worrying too much about the ramifications. This will create some of the saddest querytime that you have every had. It's true that you don't have to migrate columns as with a traditional SQL database, but if you change an attribute name and don't migrate the data, be prepared to have your queries handle the old data and the new data. There is no free lunch. :(

Tags: mongodb