Freelancing

What I learned from the hardest site I’ve ever tried to build

I know I’m not the most experienced developer in the world, but by golly I’ve built stuff. From marketplace apps to learning portals to an iOS building management app backed with a Rails backend. I’ve even built an image recognition app!

All this isn’t to brag, no sir. Just to show that I’ve actually built things, some of which were even mildly complex. All of the above though, paled in comparison to The Hardest Thing I’ve Ever Tried To Build™.

Ok enough dramatics, I was actually just trying to build my own personal site. Something simple to display my portfolio of work, maybe a contact form so people can get in touch. How hard could it be?

Very hard as it turns out.

After getting a neat coupon code from the The Guardian Football Weekly Podcast, I decided to try using Squarespace. It is the all-in-one solution for anyone looking to create a beautiful website (as per their own website). They were kind enough to give me a 14 day trial and their documentation is in video form!

Note to self : When I finally build my SAAS product, use videos for documentation, it makes things so much easier.

 You don’t really have to write any code in Squarespace. Its all drag and drop. They also give you a theme to get started, this is actually pretty good UX. Nothing makes people disappear faster then a blank canvas.

So Squarespace is pretty blameless in this, they actually provided everything I needed to build my site. The biggest barrier to building my site was in fact, myself.

I had no idea what content to put in my site, I’ve heard of copywriting, but I never though it would be this hard. Apparently just writing :

“Here’s my site, this is what I do. Hire Me!!!!”

Is nowhere near enough.

I read a few copywriting books to see if I can get better. I recommend CopyHackers, their books were really good. I applied their advice and I guess I created some half-way decent copy.That was then I realised my main enemy was’t bad copywriting.

It was fear.

I was worried, scared even. I was worried about what people will think of my site, will people spam my contact form with insults about my design, writing and my mother? Will people in the street point and laugh at me? Will children heckle me in the street and throw stones at my car?

That was when it hit me.

THIS IS THE REASON CLIENTS SEEM SO ‘PICKY’

This is the reason they ask for little changes all the time. This is the reason they seem so needy. This is the reason they never seem satisfied.

To me, this is just another app. But to the client, this is their creation, their baby. To some clients, the app I’m building is a useful add on to their business, to others it IS their business. Is it any wonder they act like helicopter parents? Hovering over you to make sure you don’t screw up?

This is one thing that separates good freelancers and bad freelancers, its important that the client trusts you before, during and even after a project. I can verify from experience that once your client has doubts about you, they go into Pointy Haired Boss in Micromanaging mode.

I probably lack this skill as of right now, its probably something I should work on for 2017.

P.S So what happened to the Squarespace site you ask? Is it live? Well….after my trial expired I was all ready to upgrade to the Basic Plan. Sadly, Squarespace rejected my card, so its back to WordPress for me!
Ruby, Ruby on Rails

Rake:notes FTW!

I just found a really cool feature in Rails, can’t believe I didn’t know about it before.

Apparently you can add comments like this in your Rails app

    def uncompleted_method
      # TODO complete this method
    end

And if you run `rake:notes` in your terminal, it will list down all the TODO comments like so

rake-notes-todo

You can also use `optimize` and `fixme` with rake:notes.

    def need_to_fix
      # FIXME fix this quickly
    end

    def optimize_this
      # OPTIMIZE this is way too slow
    end

Running rake:notes will give you:

rake-notes-todo-2

This is a really useful technique to maintain a running todo list/ reminder system in your Rails app

Ruby, Ruby on Rails

Around callbacks in ActiveRecord

Callbacks are methods that get called at certain moments of an object’s life cycle. If you’re wondering why the above sentence sounds so coherent, its because I stole it verbatim from the Rails Guides.

So most people are pretty familiar with before and after callbacks. before_save and after_update pretty much explains itself. There is another type of callback though, called around.

What in the world does it do?

What it does is it allows you to run code both before and after an operation. So an example will be like this:


class Facility < ActiveRecord::Base
  
  around_save :method_around_save
  
  private 
    def method_around_save
    # you can do stuff here
      yield <---- the save happens here
    # you can continue doing stuff here as well
    end
end

So why is this useful? Whats the difference between this and doing 2 separate before_save and after_save callbacks?

In my opinion, the around callback could be useful if you want all your database transactions in your callbacks to be atomic.

Or if you want whatever you’re doing in after_save depends on what happens before_save

Lets have a concrete example, based on a make-believe real life scenario

Say you have a Building model, which has a number of facilities under it.
Every time a building is created, you want to create a set number of hardcoded facilities.

  class Building < ActiveRecord::Base

  has_many :facilities

  after_create :create_facilities
 
  def create_facilities
    #Do facility creation here
  end
end

So each facility, will have a number of sub-facilities (Just like how badminton courts have Court A, Court B, etc). These sub-facilities are also created when the a facility is created

class Facility < ActiveRecord::Base
  after_create :create_subfacilities

  def create_subfacilities
    # sub-facilities will be created here.
  end
end

So this looks ok, I guess. But what if someone updates the facility? Maybe the user made a mistake and set the number of sub-facilities to 2 when actually there were 3 sub-facilities?

One way is to do a check before the update happens to see if the number of sub-facilities has changed (before_update) and then update the sub-facilities after the facility has been updated (after_update)

Something like this maybe?

class Facility < ActiveRecord::Base
  after_create :create_subfacilities
  before_update :check_for_subfacility_change
  after_update :sync_subfacility

  def check_for_subfacility_change
    @sync? = true if #subfacility has been changed
  end

  def sync_subfacility
    #update number of sub-facilities based on the value of @sync?
  end

  def create_subfacilities
    # sub-facilities will be created here.
  end
end

I’m just guessing here, but perhaps this could be a bit difficult to read after a few months and when the class gets bigger. So it could be easier if we did the whole thing in one around_update callback.

Perhaps something like this

class Facility < ActiveRecord::Base
  after_create :create_subfacilities
  around_update :sync_subfacility

  def sync_subfacility
   sync? = true if #subfacility has been changed
   yield
   #update sub-facilities if sync? is true
  end

  def create_subfacilities
    # sub-facilities will be created here.
  end
end

So there you go, hopefully that made sense. If you can think of a better way please reply in the comments

Ruby, Ruby on Rails

Group_by – The Definitive Guide

I’ve been working on a Rails API that sends JSON goodness to a mobile app. Its the first major app I’ve done that involves me doing the API side.

(I’ve learned that designing APIS is NOT as easy as I thought. Especially when other people have to use them.)

One of the things I had to do was to send a json load of bookings grouped by the
type of facility that was booked.

I admit I don’t religiously read the API docs for any programming language I work on, so I was embarrassingly excited when I found the group_by method

Lets read the official explaination

Collect an enumerable into sets, grouped by the result of a block. Useful, for example, for grouping records by date.

So lets break it down

1) It takes an enumerable, and like all enumerables it iterates through its contents

2) It then groups everything it iterates based on the results of the block

So imagine I had an ActiveRecordRelation with 3 booking objects

@bookings = [
  # 1,
    :facility_name => "BBQ",
    :booking_date => Wed, 30 Nov 2016>,
  # 3,
    :facility_name => "Sauna",
    :booking_date => Wed, 23 Nov 2016>,
  # 2,
    :facility_name => "BBQ",
    :booking_date => Thu, 24 Nov 2016>
]

So what if I want to group these bookings by facility name? I would do something like this.

   grouped_bookings = @bookings.group_by{ |b| b.facilty_name }

grouped_booking will return

@bookings = 
  {
    "BBQ" => [
    # 1,
      :facility_name => "BBQ",
      :booking_date => Wed, 30 Nov 2016>,
    # 2,
      :facility_name => "BBQ",
      :booking_date => Thu, 24 Nov 2016>
  ],
    "Sauna" => [
      # 3,
      :facility_name => "Sauna",
      :booking_date => Wed, 23 Nov 2016>,
    ]
  }

iOS, Swift

Time Zone fun with NSDate

The other day I had to build a booking feature where users can select a date to book a facility with a calendar.

It worked well enough, when the dates were clicked an NSDate was produced. That NSDate could then be sent to our Rails backend to store the booking.

I noticed however, that the NSDate received from the calendar gave a date from the UTC timezone.

Now, a slight segue about NSDates. According to the Apple docs

NSDate objects encapsulate a single point in time, independent of any particular calendrical system or time zone. Date objects are immutable, representing an invariant time interval relative to an absolute reference date (00:00:00 UTC on 1 January 2001).

Basically it means that an NSDate is a certain amount of integers (I assume its seconds but the Apple Docs don’t say anything about that) away from 00:00:00 UTC on 1 January 2001.

So this makes the idea of a timezone for NSDate pretty meaningless.

Thankfully, we can use NSDateFormatter to create string versions of NSDates. The NSDateFormatter has a property called timeZone that can be used to convert a NSDate to a String with the set timezone. The way I used it was as below

    func convertTimeZoneDateToString(date: String) -> String {
        let dateString = String(date)
        let dateFormatter = NSDateFormatter()
        dateFormatter.dateFormat = "yyyy-MM-dd HH:mm:ss zzzz"
        let dateObj = dateFormatter.dateFromString(dateString)
        var formattedDateString = dateFormatter.stringFromDate(dateObj!)
        dateFormatter.dateFormat = "dd-MM-yy"
        dateFormatter.timeZone = NSTimeZone(name: "MYC")
        formattedDateString = dateFormatter.stringFromDate(dateObj!)
        return formattedDateString
    }

So this will return a date with the format “dd-MM-yy” and follows the Malaysian timezone.

So thats now all well and good, but then I got a feature request where we only want to limit booking dates to 3-5 days ahead.

It would be pretty easy to compare NSDates together, we could use something like this.

    func differenceBetweenDate(currentDate: NSDate, selectedDate: NSDate) -> Int {
        let userCalendar = NSCalendar.currentCalendar()
        let dayCalendarUnit: NSCalendarUnit = [.Day]
        let dayDifference = userCalendar.components(
            dayCalendarUnit,
            fromDate: currentDate,
            toDate: selectedDate,
            options: [])
        return dayDifference.day
    }

This will return an integer of the difference in days.

Sadly,since the calendar returns a NSDate in UTC timezone, it can cause some predictable bugs since the app is supposed to live in Malaysia.

Using the earlier method wont cut it as it returns a String. So how?

After giving it some thought, I decided on doing using the string from the convertTimeZoneDateToString method and use regex to parse out the day/month/year from it. From there we can use NSDateComponents to create NSDates with the correct timezone.

Below is the method used to parse the dates with regex

    func matchesForRegexInText(regex: String!, text: String!) -> [String] {
        
        do {
            let regex = try NSRegularExpression(pattern: regex, options: [])
            let nsString = text as NSString
            let results = regex.matchesInString(text,
                                                options: [], range: NSMakeRange(0, nsString.length))
            return results.map { nsString.substringWithRange($0.range)}
        } catch let error as NSError {
            print("invalid regex: \(error.localizedDescription)")
            return []
        }
    }

An example for using this method will be:

  let date = "22-03-16"
  let dateArray = matchesForRegexInText("[0-9][0-9]", text: date)
  //dateArray = ["22","03","16"]

So then we can use NSDateComponents to create a new date. An example is:

  let date = "22-03-16"
  let calendar = NSCalendar.currentCalendar()
  let components = NSDateComponents()
  let dateArray = matchesForRegexInText("[0-9][0-9]", text: date)
  components.day = Int(dateArray[0])!
  components.month = Int(dateArray[1])!
  components.year = Int(dateArray[2])!
     
  let actualDate = calendar.dateFromComponents(components)
  return actualDate!

So now you that you have the correct date with the correct timezone. So then you can use the differenceBetweenDate method to get the difference without any unpredictable bugs.

This may be a roundabout brittle way to do things. I’m open to a better way of doing it…please.

Ruby, Ruby on Rails

Wherefore Art Thou Method?

I’ve been learning me some iOS lately, the most striking feature is the IDE, coming from Ruby and my trusty text editor, IDEs were kind of a shock. It kinda felt like someone always looking over my shoulder. Constantly pointing out what I did wrong, sometimes while in the middle of typing.

After a while I grew quite fond of Xcode, I like how you could option-click a method and see what it was all about, or at least where it was defined.

Ruby doesn’t have anything like that, at least not in the text editor. And what with its plethora of gems, its kinda hard sometimes to find where a method comes from.

I encountered a something like this earlier this week when I was trying to understand some code that was written by another developer.

The app was using  Clearance, which is a pretty nifty authentication gem. So obviously an authentication gem would need a method called “authenticate” right?  I got confused though when I saw it was used like this:

 @user = authenticate(params)

However, when I tried to use it like this:

 User.authenticate(params)

I got a

ArgumentError: wrong number of arguments (given 1, expected 2)

That was weird, looking into the Clearance gem source code, I found this in authentication.rb :

  def authenticate(params)
        Clearance.configuration.user_model.authenticate(
          params[:session][:email], params[:session][:password]
        )
      end

So obviously it accepts one argument right? Maybe another authenticate method was defined somewhere else. After hours of intense research and/or googling around for a bit, I found a method in Ruby called source_location

What this does is it tells you where a method is defined. So running this line in the rails console :

 User.method(:authenticate).source_location

will return this line:

 ["/Users/farisroslan/.rbenv/versions/2.3.0/lib/ruby/gems/2.3.0/gems/clearance-1.10.1/lib/clearance/user.rb", 19]

So it turns that there was another authenticate method defined in user.rb!

 def authenticate(email, password)
        if user = find_by_normalized_email(email)
          if password.present? && user.authenticated?(password)
            return user
          end
        end
      end

So now modifying my authenticate method for User so it looks like this:

 User.authenticate(session_params[:email],session_params[:password])

It worked well.

Now in hindsight, perhaps searching “authenticate” in the Clearance repo would have probably be quicker.Still, it should be useful if the other method is in another gem or library.

Uncategorized

Making Devise Mailers asynchronous

Devise is an awesome gem, it makes authentication for Rails apps really simple. One problem I faced was trying to make Devise mailers asynchronous. This kinda sorta worked, sometimes emails from devise will come almost immediately, sometimes it won’t come at all. Obviously, inconsistency is Not Good.

I figured the devise-async gem was to blame for this. So I decided to dive into it and see what I could find. Code reading is supposed to make you smarter anyway.

First thing I did was fork the gem, that way a copy appears on my github for me to modify and use. To use my own version of the gem I write this in my gemfile:

gem 'devise-async', git: "git://github.com/hewrin/devise-async.git"

With “hewrin” being my username.

Looking at tests are a good way to find out what a gem/app does. Unfortunately nobody told me about this when I first began diving in. All I did was insert “byebug” everywhere and send a devise email. But first, lets look at the Big Picture.

devise-async is a small gem, all the important stuff happens in the lib folder. To be more specific, the important stuff happens in the devise folder in the lib folder. Lets first look at the async.rb file.

From what I understand, this file is extending the Devise module by adding the Async feature. The file is pretty well commented, so its pretty simple to figure out what it does. The only interesting thing I found was mattr_accessor

mattr_accessor is like attr_accessor, difference is it creates getter/setter methods for modules instead of instances. This makes it easy for people to modify things in the initializers folder in a Rails app. The setup method at the bottom is what allows users to modify the configuration of the gem.

    def self.setup
      yield self
    end

I haven’t encountered this before, it seems doing yield self loads up the whole Module, allowing us access to all mattr_accessor .

The kind people who created the gem even gave us an example:

    Devise::Async.setup do |config|
      config.backend = :sidekiq
      config.queue   = :default
    end

In the example above, config.backend pretty much means Devise::Async.backend. So putting the above in a file in my initializers folder will set Sidekiq as my backend and the queue name as default.

Finally, at the bottom there is a method that adds the Async module to devise, this is what allows us to add devise :async in our model files to make the mailers asynchronous, just like when we add :confirmable to send confirmation emails.

The Devise.add_module method is quite interesting. Below is the source code of the method, taken from Devise:

    def self.add_module(m)
      class_eval <<-METHOD, __FILE__, __LINE__ + 1
        def #{m}?
          self.modules.include?(:#{m})
        end
      METHOD
    end

This…will be discussed in my next post.