Exceptions in Ruby

Why do we do exception handling? Sometimes things don’t execute the way they are designed to, for reasons outside of our code’s responsibilty. Maybe your code relies on something external, for example, scraping, an external server, an API. If your code uses external input, exceptions are a way of handling any exceptions to the expected outcome.

In many ways, exceptions are similar to conditionals. The exception handling block in Ruby, the begin...rescue block, is not unlike an if...else conditional statement; they both control flow. Exceptions account for the possibility of something happening and accounting for that, not unlike conditional statements.

Let’s look at a simple example method in Ruby:

1
2
3
def plus_one(num)
  num += 1
end

When we run plus_one("22"), as you can guess, we’re going to get the following error returned:

1
# => TypeError: String can't be coerced into Fixnum

If we wanted to avoid that TypeError from happening, which would break our program at runtime, we could write a conditional that expects input that’s not a number and sanitizes it:

1
2
3
4
5
6
7
def plus_one(num)
  if !num.is_a?(Fixnum)
    num.to_f
  else
    num += 1
  end
end

But what if you wanted to know about that error, not just go ahead and fix it? Or maybe you really cannot fix the input yourself, because it’s coming from somewhere else. Or, most commonly, you just need to handle the error and keep things running.

That’s where exception handling comes in:

1
2
3
4
5
6
7
def plus_one(num)
  begin
    num += 1
  rescue
    puts "Can't add a #{num.class} '#{num}' to an integer. Please make sure the input is an integer."
  end
end

The begin...rescue block works as such that when begin is triggered, it’s going to try to execute whatever code is in that block, and, if for whatever reason it can’t (for example, a TypeError), it’s going to fall down to the rescue block and execute the code in that block instead. This way, our program won’t crash if there’s an error.

Our contrived example doesn’t really lend itself to anything other than what it is, but the fact that exception handling prevents our program from crashing is very important. If our code relies on data that is external, we don’t have full control over it. It can change. That’s the power of exception handling: our program will not break if what it relies on changes.

So our begin...rescue block is pretty cool, but we can take exception handling even further if we need to.

In our above begin...rescue block, num += 1 will only be called if an error isn’t raised during its execution. What if, regardless of that code being run, we want something else to always execute? That’s where the ensure block comes in.

1
2
3
4
5
6
7
8
9
def plus_one(num)
  begin
    num += 1
  rescue
    puts "Can't add a #{num.class} '#{num}' to an integer. Please make sure the input is an integer."
  ensure
    puts "You'll always see me!"
  end
end

Ensure happens after both the begin and rescue blocks are ran, and will always execute, hence the name ensure.

Exceptions like begin...rescue are great for just that, throwing exception messages. While they act like conditional expressions, they really should never be used for managing conditional flow. They should be reserved for providing information when something went wrong, handling what happens when that error occurs, and keep things flowing. The reasoning for this isn’t a stylistic choice: figuring out where and why something went wrong takes time. Exception handling is slow, and conditional flow, part of everyday development, should be fast.

Up next, I’ll talk about another option for programmatic flow in Ruby: try...catch.

Building a Single Page Web App for Mobile

I few weeks ago, I was faced with a dilemma. I really like playing the game Carcassonne, and I wanted to be able to bring the game with me when I traveled, but while the pieces – small cardboard squares – can easily fit into a small bag, the board used to tally players’ scores is larger and awkward to travel with. So I decided to solve this problem by building an app to replace the board. The app needed to allow a selected number of users (who can choose their meeple color) to be able to increment their count by clicking the number representing that count.

Most importantly, the app also needed to be mobile-friendly from the start, because it would mostly likely always be accessed from someone’s telephone while traveling. The focus of this project was to make the app mobile-browser ready, without needing to build iOS and Android apps. I’m going to walk through how I used JavaScript, HTML, CSS, responsive design principles, and Rack to make this simple app called Carcassonne Counter. Ultimately this is an example of building something with tools at hand that is entirely mobile responsive and user-friendly.

The first task was to get the basic logic and functionality in place for user interaction. Client-side JavaScript is obviously perfect for this. I decided to go to town on the it as an exercise in writing good, clean JavaScript, but that’s for another blog post. But to give a general background of what the app is doing:

  • a user can select the number of players and their colors
  • .onClick() the user increments the score count by one
  • There are Player prototypes that:
    • keep track of player scores and color
    • methods to reset the game
    • decrement the score (if you make a mistake through overeager clicking)
    • and a bunch of jQuery powered front-end methods

Let’s dive in to some effective and easy ways to make a web app completely mobile friendly, with as close as possible functionality to any simple iOS or Android app that achieves the same thing.

The Layout

The app is a single page / single user experience design. The main focus of the page is each players’ block, which holds their score number with the background-color of whichever color they selected. The templates for each number of players is hard-coded into the index.html page, because I think it makes more sense than dynamically rendering it, given how there are only 5 different templates.

Here’s what the app looks like for a two player game with blue and red meeples:

The entire page, no matter how many players were in the game (2-6), needed to be entirely fit for a mobile screen. For this I set the height and width to view width (vw) and view height (vh). CSS selectors, from body to each container for a players’ block, use vw and vh instead of pecentages or pixels. This means that no matter the size of the screen (an iPhone 6 vs a Nexus 7 vs a Moto X) the color block, given the HTML template, will fit the view’s width and height. This fixes the size of that HTML element to whatever “percentage” is selected. So for the above two player template, the CSS looks like this:

1
2
3
4
5
#container2 .player {
  width: 100vw;
  height: 50vh;
  line-height: 50vh;
}

This remains entirely responsive to whatever size screen / device the app is viewed on.

Clicking / Tapping Functionality

The main functionality of this app is clicking, or in the case of mobile use, tapping. One problem I encountered with the tapping functionality was that most mobile devices initialize double-tapping zoom as soon as tapping reaches a certain speed. On this single page, given that the view’s width and height is always fixed to the size of the screen, zooming isn’t necessary. I needed a way to disable that double-tap feature to allow for rapid tallying.

First step is including in the <head> a meta property that disables the user’s ability to change the view of the screen. This prevents the double-tapping zoom:

1
<meta name="viewport" content="user-scalable=no" />

Next, in order to utilize that double-tap functionality for rapid tapping, I used a super simple and easy JavaScript plugin called jQuery Finger.

In addition to setting an event handler on tap…

1
2
$(".player" + this.number).on("tap", function() {
  this.incrementNumber(); }.bind(this));

…you can also set one on double tap, using jQuery Finger’s custom event handler:

1
2
$(".player" + this.number).on("doubletap", function() {
  this.incrementNumber(); }.bind(this));

Focused Swiping Functionality

What if a player accidentally increments their tally, and they need to subtract some points? Swiping backwards on the number area where you’re tapping to increment is a logical gesture. jQuery Finger has an event handler for that as well:

1
2
$(".player" + this.number).on("flick", function() {
  this.decrementNumber(); }.bind(this));

Rack

Finally, I turned the single page application into a Rack app. This was entirely out of laziness, because I wanted to be able to host it easily, and Heroku is great for that. There are pluses and minuses to static Rack websites, and I won’t go too much into that only to say I think it’s fine for small, single page, side projects like this. I mostly followed this helpful guide on Heroku on how to set up a config.ru file.

Conclusion

Eventually I would love for Carcassonne Counter to be turned into something that’s in the App Store / Google Play Store, but ultimately this solution makes the most sense given the simple problem and the usage. The app is completely responsive for any sized screen, which makes it pretty versatile for users, and has many of the same mobile gesture capabilites as an iOS/Android app. Ultimately I’ll be building a Rails backend to persist game data and support other game counting/scoring as well, and at that point, this app will most likely be expanded on substantially, and perhaps I’ll even delve into making at iOS/Android then.

Testing Rails jBuilder JSON APIs With RSpec

When I first embarked on creating an API for a project, I couldn’t find a ton of resources on how to test it with RSpec, so I decided to write a blog post about it.

Let’s say we’re building an app that allows users to list their second bedrooms to short-term guests. We all love Airbnb :)

This would be an application with many models that have complex associations, but let’s focus on what a host can do with their listing(s). They can create a new one, edit it, and delete it. A user can view one listing, or many listings (given certain filters like price, listing type, availability, city, etc). Let’s focus on the GET /listings, POST /listings, and DELETE /listings/:id requests that our API would support.

Here’s the listings controller. This controller ultimately inherits from ActionController::Base, and I’m using jbuilder to format the rendered JSON. Pretty straightforward.

The Tests

The first thing we need to do is tell each test to render_views, as we’re rendering JSON via jbuilder, and these are handled by Rails as views. This should go at the top before any tests.

1
2
3
4
5
6
RSpec.describe ListingsController, :type => :controller do
  render_views

  let(:json) { JSON.parse(response.body) }

  # describe...

GET

The GET /listings request should return all of the listings, with or without a filter. A simple test for this needs to:

  • make a GET request to the index method and specify the format we’re responding with (json)
  • parse the response body into a JSON object so we can see what we’re getting back from the request (which I’ve done once, above, in a let block, because this is a repeated action)
  • body looks like this:
1
2
3
4
5
6
 [{"id"=>1,
   "listing_type"=>"private room",
   "title"=>"Beautiful Apartment on Main Street",
   "price"=>"50.0",
 ....
   {"id"=>2...}]
  • grab some of that JSON data to assert an expectation on
  • test that the data is what we expect it to be (against some data in our test database, in this case I just built this in a before(:each) block in my rails_helper)

Here we go:

1
2
3
4
5
6
7
8
9
10
describe "GET /listings.json" do
  before do
    get :index, format: :json
  end

  context 'all listings' do
    it 'returns the listings' do
      expect(json.collect{|l| l["title"]}).to include(@listing1.title)
    end
  end

Next let’s test that we can return all the listings of a certain price, price being a parameter. In my listings controller, there’s an index method with a conditional to check for a params[:price], and if that was given, return all listings where “price” is that price. Our test for this will look very much like the above test, except we’re accounting for price, which is passed into a get :index method along with format.

1
2
3
4
5
6
7
8
9
context 'all listings given price filter' do
  before do
    get :index, format: :json, price: 50.0
  end

  it 'returns the listings' do
    expect(json.collect{|l| l["title"]}).to include(@listing1.title)
  end
end

POST

Now let’s work on testing our POST /listings.json request. We’re going to test that it can work (creating a new listing object in our database) and that it can fail (returning a 422).

Our success test will function much like our test for our above get requests. Instead it will call the post :create method which specifies the format as well as the required params for :listing, which we specified in a private method listing_params in our controller.

1
2
3
4
5
6
7
8
9
10
describe 'POST /listings.json' do
  context 'new listing success' do
    before do
      post :create, format: :json, :listing => {address: "123 Testing Lane", listing_type: "shared room", title: "Testing Listing", description: "idk", price: 1000.00, neighborhood_id: 1, host_id: 1}
    end

    it 'creates a new listing' do
      expect(Listing.last.address).to eq("123 Testing Lane")
    end
  end

Let’s also test that a failure will happen without the expected params (setting neighborhood_id to nil). There’s a validation on the listing model where a listing must have an associated neighborhood, which I’ve already tested in a model test. However, I wanted to test that the controller would return a 422 if the validation doesn’t pass. Here we go:

1
2
3
4
5
6
7
8
9
context 'new listing failure' do
  before do
    post :create, format: :json, :listing => {address: "123 Testing Lane", listing_type: "shared room", title: "Testing Listing", description: "idk", price: 1000.00, neighborhood_id: nil, host_id: 1}
  end

  it 'responds with 422' do
    expect(response.status).to eq(422)
  end
end

DELETE

Last, let’s test deleting a listing. We want to call the delete :destroy method with the format and the id params specified (we’re going to delete the first item in our test database). We want to test that the controller destroy method deletes the record from the database.

1
2
3
4
5
6
7
8
9
10
11
describe 'DELETE /listings/:id.json' do
  before do
    delete :destroy, format: :json, id: 1
  end

  context 'delete a listing' do
    it 'deletes a listing' do
      expect(Listing.where(id: 1)).to be_empty
    end
  end
end

There we go! RSpec makes it easy to test Rails APIs by simulating HTTP requests via get, post, patch, and delete methods. Below are some gists of the code in full discussed in this post.

Code

Pass by Value vs. Pass by Reference in Ruby

Recently my world was turned upside down by something that happened while iterating over an array with the each method. It went something like this:

1
2
3
["cats", "dogs", "squirrels"].each do |word|
  word << "!"
end

I expected that the return value of this block to be this:

1
["cats", "dogs", "squirrels"]

But instead, it was this:

1
["cats!", "dogs!", "squirrels!"]

Being a beginner still in many ways, I’m awarded moments like this where I can learn something new about something I before took for granted. I’m used to iterating over an array with each and having the return value be the original array, because I assumed that the each method never altered the array:

1
2
3
4
[1,2,3].each do |num|
  num += 1
end
# => [1, 2, 3] 

That’s not always the case.

Why? Objects in programming languages, in this context Ruby (it may be different in other languages), are either passed by value or passed by reference. Primitive data like integers, floats, fixnums, and symbols require a fixed, small amount of memory, so therefore are passed by their value. Objects that can grow and change, like arrays and strings, are never a fixed size. They are instead always referenced by some pointer, in order to save memory use in a program.

Thus, certain objects like strings and arrays are mutable within an each method:

1
2
3
4
[[1], [2], [3]].each do |array|
  array << 1
end
# => [[1, 1], [2, 1], [3, 1]]

Here’s another, albeit not super elegant, illustration of the (im)mutability of objects that are passed by value vs. passed by reference:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
array= [1]
string = "1"
number = 1

def push(object)
  object << 1
end

# objects that are passed by reference are changed:

push(array)
# => [1,1]
array
# => [1,1]

push(string)
# => "1\u0001"
string
# => "1\u0001"

# objects that are passed by value are not changed:
push(number)
# => 2
number
# => 1

The distinction between pass by value and pass by reference is important. It helps determine whether or not your method modifies certain types of data passed into that method that are also used by the rest of a program. If your data can be passed by reference, it’s worth it to be mindful of a method’s affect on it.

Refactoring in Ruby

Lately I’ve been giving a lot of thought into not just making something work, but making it cleaner. I’ve been reading Sandi Metz’s Practical Object Oriented Design in Ruby, which although not explicitly about refactoring, seems to have gotten me in the frame of mind to think about it. Part of me thinks this marks a shift for me from level beginner to intermediate, but actually no, because I always want to be a beginner, and also, I’m actually still really a beginner. :)

When thinking about effective teaching at Flatiron (side note: I’m back! It’s awesome), we believe in the idea of “Make it work. Make it right. Make it fast”, a concept coined by Kent Beck back in the day. An effective learning process almost demands this concept: get it working so you can learn how it works, and for the sake of accomplishment. I believe this is paramount to being a junior developer. Before you learn how to be good, you need to just learn how to do it. The good part will come with time, practice, and studying eloquent code (see: POODR).

I’ve been doing just that, and have been thinking about giving more time to refactoring and taking pride in making my code the best it can be (and like everything, it can always be better).

I’ve been working on a simple side project that makes calls to the Github API. I’ve been using the Typhoeus gem for making the requests (it’s a great gem to learn to use, for its versatility). Before refactoring, I had a bunch of methods within a class (or model, as it’s a Rails app) that each work as an API call for something specific (to get an organization, repo, etc).

Here’s what it looked like:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
class GithubConnection
  attr_reader :username, :token, :orgs, :repos, :issues

  def initialize(github_data)
    @username = github_data["username"]
    @token = github_data["token"]
  end

  def get_organizations
    request = Typhoeus::Request.new(
      "https://api.github.com/user/orgs",
      headers: {Authorization: "token #{token}"}
    )
    response = request.run
    orgs = JSON.parse(response.body).map do |org|
      org["login"]
    end
  end

  def get_repos(organization)
    request = Typhoeus::Request.new(
      "https://api.github.com/orgs/#{organization}/repos",
      headers: {Authorization: "token #{token}"}
      )
    response = request.run
    repos = JSON.parse(response.body).map do |repo|
      repo["name"]
    end
  end

  def get_issues(organization, repo)
    request = Typhoeus::Request.new(
      "https://api.github.com/#{organization}/#{repo}/issues",
      headers: {Authorization: "token #{token}"}
      )
    response = request.run
    repos = JSON.parse(response.body).map do |issue|
      issue
    end
  end

end

Each method (get_organizations, get_repos, and get_issues) has a specific purpose (which is great! A method should be a single unit of work). But something smells, even just a little bit. I’ve been repeating myself, with my request = Typhoeus::Request.new... and handling the responses via parsing. This breaks the number one rule of clean code: DRY. Don’t Repeat Yourself. Whoops. It’s okay, because these methods get the job done. But I can do a little better.

I began to think about how to fix this. What are the units of functionality that are repeated? What are they doing? And, what are the unique portions of those repeated parts (as in, why was I repeating myself)? How can I abstract out the repetition, and account for the unique parts?

Generally, each method makes an API call. The unique part is what the call is calling to. Each method is taking the response of that call and iterating through to get the data that I want. The unique part of that looping is simply what is being iterated over. I can rewrite the above into a single method that given unique data within its parameters, handles this. Note that I need to pass in an optional key; remember above that when iterating through the JSON object, some of the data I’m extracting is the value in a key:value pair.

1
2
3
4
5
6
7
  def get_data(url, key=nil)
    request = Typhoeus::Request.new(url, headers: {Authorization: "token #{token}"})
    response = request.run
    JSON.parse(response.body).map do |to_parse|
      key ? to_parse[key] : to_parse
    end
  end

This method encapsulates two units of work. This breaks the rule of separation of concerns. If we follow that rule, a method should really only be responsible for one unit of functionality.

With that, it’s a bit clearer how I could further refactor. I can make two methods that are each a unit of functionality that take in some unique information and use that information to return different values. First, I’ll make a method that is a scaffold for some API call, given what I want to call to (which is passed in as parameters).

1
2
3
4
  def make_request(url, header)
    request = Typhoeus::Request.new(url, header)
    response = request.run
  end

Then I’ll have a separate method that handles the response of that call (it calls the make_request method within it), parsing it and returning the data I want, given the API url provided.

1
2
3
4
5
  def json_parse(url, key=nil)
    JSON.parse(make_request(url, headers: {Authorization: "token #{token}"}).body).map do |to_parse|
      key ? to_parse[key] : to_parse
    end
  end

For the sake of my application structure, I’d like to have methods for each of those individual API calls, so I can call them on instances of the class within the controller (this is primarily for clarity on the controller end; @instance.get_organizations is easily understood at first glance).

1
2
3
4
5
6
7
8
9
10
11
  def get_organizations
    orgs = json_parse("https://api.github.com/user/orgs", "login")
  end

  def get_repos(organization)
    repos = json_parse("https://api.github.com/orgs/#{organization}/repos", "name")
  end

  def get_issues(organization, repo)
    issues = json_parse("https://api.github.com/repos/#{organization}/#{repo}/issues")
  end

I could take it farther than this and refactor even more, but this is clear, concise, and has just enough syntactic sugar without being unreadable at first glance to fellow developers. The best refactoring should do this without sacrificing readability.

Getting Sassy

I recently saw on Twitter someone referring to CSS as a Cascading Shit Show. I can’t remember who said it to give credit, but I wish I did, because it’s rather accurate.

I’m of this persuasion as well because with all of my projects, my approach to CSS seems, to me, to be sloppy and all over the place. I try to keep things organized, but it still seems unruly, or at the very least, very cascading.

I decided to dive into Sass, because it clears up these frustrations with CSS by allowing variables, inheritance (nesting and extending), and mixins. To play around with these features, I decided to refactor the style of a small project, My Etsy Map.

Get the Sass

First, if you’re building a Ruby app without Sass pre-compiling (like Rails), you will need to include the sass gem in your Gemfile. My app here is a Sinatra app, which uses Rack, so not only did I have to include the gem, but in the config.ru file, I needed to include the sass/plugin/rack and use the appropriate Middleware (Sass::Plugin::Rack).

Some Sass

To start, I went through and refactored for DRY-ness. I noticed some repeated styles that I could abstract out into variables:

1
2
$primary-height: 100%;
$primary-bg-color: rgba(245, 245, 245, 0.8);

I decided to got even more fancy and incorporate some mixins, because I had a couple of CSS3 styles that require browser specificity. mixins work like methods that take in parameters. Then you can call them later with include, while providing the appropriate value:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
@mixin background-size($size) {
  -webkit-background-size: $size;
  -moz-background-size: $size;
  -o-background-size: $size;
  background-size: $size;
}

@mixin border-radius($radius) {
  -webkit-border-radius: $radius;
  -moz-border-radius: $radius;
  -ms-border-radius: $radius;
  -o-border-radius: $radius;
  border-radius: $radius;
}

//and later:
@include background-size(cover);

@include border-radius(5px);

I also played around with nesting, making use of the & to reference the parent selectors on my a:hover:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
.footer {
  position: absolute;
  bottom: 0;
  margin-top: -60px;
  height: 60px;
  clear: both;
  padding-top: 20px;
  background-color: $primary-bg-color;
  width: 100%;
  a {
  color: #5CB85C;
  &:hover { color: #3d8b3d; }
  }
}

The CSS output of this assigns the .footer class to the a element and the hover selector styles; this saves me from typing .footer on all of the elements that have that class, as well as keeps it organized.

1
2
3
4
5
6
7
8
9
10
11
12
13
.footer {
  position: absolute;
  bottom: 0;
  margin-top: -60px;
  height: 60px;
  clear: both;
  padding-top: 20px;
  background-color: rgba(245, 245, 245, 0.8);
  width: 100%; }
  .footer a {
    color: #5CB85C; }
    .footer a:hover {
      color: #3d8b3d; }

Compiling

Compiling Sass into CSS is necessary, as the browser only reads CSS. After I wrote my styles in a Sass file (.scss), I had to Sass-ify it by simply running the sass command within the root drectory of my project, where your .scss file is turned into a .css file. The sass command takes [options], like the super useful —watch, which as you can guess, watches for changes to your .scss and compiles the .css as the changes are made. But if you just want to simply compile, just include the [input] (.scss) and the [output] (.css) files.

Sass is super fun and coming from Ruby, logically familiar to me. I’m excited to start incorporating it into all of my projects from now on, as it clears up most of the frustrations with CSS.

From Ruby to PHP

Here in my blog, I’ve been chronicling my journey to learn PHP, coming from Ruby as my first programming language. It’s been a interesting journey so far; while PHP and Ruby share some similarities as scripting languages, the other components and technologies surrounding them are different, at least for me as a beginner in PHP. I wanted to write a blog post about the certain steps I’ve made, including outlining the resources I’ve found and the stacks I’ve been learning in this transition. If you’re coming from Ruby to PHP, I hope this post can help you get started.

After I got the building blocks of PHP out of the way, learning the new syntax through various resources (including Codecademy) and books, I took the next step in my learning by re-envisioning a project I worked on during my time at Flatiron called GuideMe. My choice to take a project I had already done was for a few reasons: The models and their relationships have already been imagined, so I could jump right into learning a new ORM more easily; I also have all of the styling (Bootstrap and otherwise) set up, which would make my project look prettier during the beginning stages of coding it; And, in this case, GuideMe is a relatively uncomplicated concept that would allow me to concentrate on learning the stacks. I think all of this helps for a first major project in another language.

With the help of the incredibly patient and helpful Matthew Turland, whose been a great resource during my journey into PHP, I came up with a strategy on how to tackle this project. First I should note that it is my impression, given my experience (and this could be from my then limited exposure working with the technologies Flatiron focused on), Ruby is relatively contained: to get the job done, there are a few well constructed technologies that basically everyone uses (for example, Bundler, ERB, Rails, or Sinatra). However, in the PHP world, there are many choices of tools to use (different dependency management strategies, many different frameworks, and various templating options).

I decided to work with things I found relatively similar to what I’ve been working with in Ruby, simply because these Ruby technologies work well. I’m going to go through each part of my stack I’m currently working on and discuss what makes them great for Rubyists turned PHPists.

Composer

I’ll admit I chose Composer because it’s what we’re currently using at my company. It’s relatively new, but the documentation is solid and it’s not unlike Bundler for managing your Ruby gems. Installing composer within your project directory creates a composer.json file, where you can require all of your dependencies and files for autoload.

Doctrine ORM

Doctrine ORM is a DataMapper ORM that I chose to learn because, again, the documentation is pretty straightforward. They have a tutorial that’s helpful in walking you through setting up a simple project. With Doctrine, you create entities, or models, that serve to map your objects onto a database. Each model is a class, and within that class, you can map your object’s relations to other objects. Below is my model for my Topic object:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
use Doctrine\Common\Collections\ArrayCollection;
/**
 * @Entity @Table(name="topics")
 **/
class Topic {
  /** @Id @Column(type="integer") @GeneratedValue **/
  protected $id;
  /**
   * @Column(type="string")
   * @var string
   */
  protected $title;
  /**
   * @Column(type="string")
   * @var string
   */
  protected $description;
  /**
   * @ManyToOne(targetEntity="User", inversedBy="topics")
   **/
  protected $user;
  /**
   * @OneToMany(targetEntity="Suggestion", mappedBy="topic")
   * @var Suggestion[]
   **/
  protected $suggestions;
  /**
   * @ManyToMany(targetEntity="Tag", inversedBy="topics")
   * @JoinTable(name="topics_tags")
   **/
  protected $tags;

  public function __construct() {
    $this->tags = new ArrayCollection();
    $this->suggestions = new ArrayCollection();
  }

  public function getId() {
    return $this->id;
  }

  public function getTitle() {
    return $this->title;
  }

  public function setTitle($title) {
    $this->title = $title;
  }

  public function getDescription() {
    return $this->description;
  }

  public function setDescription($description) {
    $this->description = $description;
  }

  public function getUser() {
    return $this->user;
  }

  public function setUser($user) {
    $this->user = $user;
  }

  public function getSuggestions() {
    return $this->suggestions;
  }

  public function setSuggestions($suggestions) {
    $this->suggestions = $suggestions;
  }

  public function getTags() {
    return $this->tags;
  }

  public function setTags($tags) {
    $this->tags = $tags;
  }
}

Let’s say I have a page that displays all of the topics. With my above model in place, I can then iterate through $topics (managed by the entityManager class, as outlined here) like so:

1
2
3
4
5
6
foreach ($topics as $topic) {
  echo $topic->getTitle()
  echo $topic->getDescription()
  echo $topic->getUser()->getName()
  ...
}

Slim Framework

Slim is a lightweight framework inspired by Sinatra. The documentation for it is great, and for those that love Sinatra, it’s familiar.

Once Slim is required by Composer (so easy!), within the home directory of your project, set up an index.php file (like app.rb in Sinatra), where you’ll keep your routes and instantiate a new Slim object (your app). For sake of clarity, depending on the size of the project, you can keep index.php as the runner file to run your application, and require other route files that you can organize elsewhere (I have a routes directory I keep them all in, and each file corresponds with an object; while called routes, I like to think of them as Controllers).

Here’s an example of a route in Slim, taken from the documentation. Not unlike Sinatra at all!

1
2
3
$app->get('/hello/:name', function ($name) {
    echo "Hello, $name";
});

There are also full-stack frameworks within the PHP world. The two most popular ones that have evolved nicely with the language are Symfony and Zend.

Templating

There are many options for templating in PHP. While both Twig and Smarty are quite popular, I wanted to go with something that didn’t require learning another markdown language, but instead uses PHP; essentially I wanted the ERB equivalent. Savant3 is incredibly easy to use. The bulk of what it does is pass your object to an instance of the Savant class. Here is my route for displaying one topic by id. I create a new instance of the Savant class, $tpl, pass my already collected instance of Topic ($topic) to it, and then render it through Savant’s display() method:

1
2
3
4
5
6
7
8
9
$app->get('/topics/:id', function($id) use($entityManager) {

  $topic = $entityManager->find("Topic", (int)$id);

  $tpl = new Savant3();
  $tpl->topic = $topic;
  $tpl->display('views/topics/show.tpl.php');

});

In my show.tpl.php file, I refer to $tpl->topic as $this->topic. Passing the object like this as well passes all of its class functions, like getTitle(), getUser(), etc.

Conclusion

PHP has a lot of tools out there for web development; I chose all of these because they embody characteristics of similar tools in Ruby that I love. I’m open to any suggestions for other great tools from those who code in both Ruby and PHP! :)

Closures in PHP

Like JavaScript, PHP as well has anonymous functions, also referred to as closures (while related, not the same as closures in functional programming). I first came across anonymous functions in JavaScript, but recently learned about their PHP counterpart while playing around with Slim, a PHP framework not unlike Sinatra, which I ♥. Closures are an important part of route declarations in Slim:

1
2
3
4
5
6
<?php
//taken from the Slim Documentation:
$app->get('/hello/:name', function ($name) {
    echo "Hello, $name";
});
?>

The application that I am building on Slim uses Doctrine ORM. The ORM handles object retrieval through the EntityManager class. Using a call to EntityManager, I can access my objects and then be able to use them within my application.

1
2
3
4
<?php
// obtaining the entity manager; $conn is my database access and $config is my model configuration
$entityManager = EntityManager::create($conn, $config);
?>

I still needed a way to pass the instance of EntityManager to my Slim routes. One way, of course, would be to make this instance a global variable. While useful, global variables are not the cleanest way to code. I might not want every function in my application to have access to this variable.

However, closures in PHP can inherit variables from the parent scope in a much more controlled and cleaner way with the use construct. The parent scope of the closure is where the closure is declared, and lucky for me, my code is organized as such that my $entityManager declaration lives in that same scope.

1
2
3
4
5
6
7
8
9
<?php
$app->get('/topics', function() use($entityManager) {
  $dql = "SELECT t, u FROM Topic t JOIN t.user u ORDER BY t.id DESC";
  $query = $entityManager->createQuery($dql);
  $topics = $query->getResult();

  //I'm dynamically doing things with my $topics here
});
?>

FULLTEXT in MySQL

When querying your database of cats (as one does) using MySQL, sometimes a simple SELECT * FROM cats WHERE bio LIKE '%boxes%'; is either not strong enough (this query would obviously return many cats), or just inefficient and expensive, as it results in a full table scan. Instead, a FULLTEXT search is more nuanced, allowing you to run more explicit and multi-worded queries on your database.

There is one thing to first think about in regards to FULLTEXT. First, depending on the version of MySQL you are using, FULLTEXT may only work on a MyISAM type table (as of 5.6, InnoDB also supports FULLTEXT). I could write a whole post about the differences between MyISAM and InnoDB, but for now, this Stack Overflow post sums it up nicely instead.

Once you know your engine type and its FULLTEXT search capabilities, the first step is to make sure that the columns you want to query are indexed for FULLTEXT. If your table is already created, the ALTER command is necessary to change it.

In my table Cats, there are the following columns: cat_id, name, age, gender, breed, location, and bio. Let’s say I want to be able to run a FULLTEXT search on cats’ biographies:

ALTER TABLE cats ADD FULLTEXT (bio);

Running a FULLTEXT search is simple with the use of a WHERE clause, with a MATCH...AGAINST added in:

SELECT name, bio FROM cats WHERE MATCH (bio) AGAINST ('boxes Japan');

(In my example, this would return Maru.)

FULLTEXT has some important rules. Keywords that are less than four characters will be ignored; popular words (stopwords, like ‘and’, ‘the’, etc.) are also ignored; and, if more than half of the record match the keywords, the query won’t return anything at all. This last one is important and should be remembered, as you can become puzzled when your search returns nothing. This is because FULLTEXT wants to return relevant, specific results.

There are also some useful parameters that can help querying even further. Add IN BOOLEAN MODE to the AGAINST clause, and you can further specify if a word must be included (‘+boxes’) or excluded (‘-California’), as well as a word and its variations (the wildcard: ‘box*’ can return ‘box’ and ‘boxes’). It should be noted if you’re using boolean mode, the results will not be ordered or sorted by relevance. An ORDER BY clause after the AGAINST clause with the parameters you need will do this. Borrowing from my previous example, let’s say I’m looking for cats who like boxes, but I’m most interested in those who also live in Japan:

1
2
3
4
5
6
SELECT name, bio, 
  MATCH (bio) AGAINST ('boxes >Japan' IN BOOLEAN MODE) 
  AS japanese_box_relevance 
FROM cats 
WHERE MATCH (bio) AGAINST ('boxes >Japan' IN BOOLEAN MODE) 
ORDER BY japanese_box_relevance DESC;

FULLTEXT is a great feature of MyISAM/newer InnoDB tables, but there are some drawbacks. If you’re strictly InnoDB and using an older version of MySQL, or you have heavy traffic, for example, you may need other options, like a strictly fulltext search server like Sphinx.

Notes on SQL

In part with my PHP learning, I am reading Larry Ullman’s PHP and MySQL for Dynamic Websites, which has been reintroducing me to raw SQL statements, after living in Railsland for the last two months. I had forgotten how much I love SQL, for its clean querying and data organizing.

One thing that we were left to think about at Flatiron was the idea of code as a story. Code tells the story of your web application: there’s the setting, characters, and information about the characters. Databases are the heart of that story, because they illustrate the connections between your code’s characters. And SQL’s JOIN query is at the heart of how these connections are told.

As a refresher, JOIN is a query that uses two or more tables, essentially creating a virtual table between them (you never really see this table, however). The most common join, and the focus of my post is the inner join. An inner join returns all of the database records from the named tables where a match is made on the specified criteria.

I’m going to be lazy about my examples here and adapt them from Larry Ullman’s forum. A brief synopsis of the story about the forum. This database has messages table (a message has a subject, name, message, posted date, etc), a forum table (a forum has a subject), and users table (a user has a name, email, password, etc). On these tables, there are primary keys as integers. The relationship is that a message has one user and one forum (so there are foreign keys* for both on the messages table).

Let’s say I want to find all of the messages on a forum that have the subject “Cats”. There are three ways to do this.

The first does not actually utilize a JOIN statement:

1
2
3
SELECT m.message_id, m.subject, f.subject
FROM messages AS m, forums AS f
WHERE m.forum_id = f.forum_id AND f.subject = "Cats"

The downside of running this query is that it overloads the WHERE clause, both limiting (where the forum_ids match) and describing (the forum subject as “Cats”). This isn’t necessarily more expensive on the database, but it is not the clearest way to query.

Using a JOIN is cleaner and more descriptive:

1
2
3
4
SELECT m.message_id, m.subject, f.subject
FROM messages AS m JOIN forums AS f
ON m.forum_id = f.forum_id
WHERE f.subject = "Cats"

Here I’m using the ON clause to describe the relationship between the forum_id in the forum’s table and the forum_id (as a foreign key) on the messages table.

For some syntactic sugar, there’s an even nicer way to write this with a USING clause:

1
2
3
4
SELECT m.message_id, m.subject, f.subject
FROM messages AS m JOIN forums AS f
USING (forum_id)
WHERE f.subject = "Cats"

A USING clause is only possible if you name your primary key the same way in both tables. In this case, a clean way of doing that is tablename_id.

This is a very common type of query on a database, so writing it the way that seems cleanest is an important practice. I like the sound of the USING clause, so therefore prefer it.

*Foreign keys connect two tables in order to illustrate the relationship between them, and most importantly, to prevent bad data. A message’s forum_id as a foreign key points back to a forum’s id, signaling that that message belongs to that forum. So if you want to delete an entire forum, having the forum_id on the messages that belong to it prevents you from doing so without first deleting those messages. Without a foreign key in place, you can be left with bad data: messages from a deleted forum are left lying around.