Food For Thought

This post may seem a bit out of place on the blog and I guess that’s because it is. In a nutshell: I got sick, I learned how to eat and I got better. These are my current thoughts on food and nutrition. We’re all different, as always do what’s best for your snowflake of a body.

There’s always talk of low carb or high protein or zero fat or … but they’re missing the point. It’s not one versus the other it’s which of each.

We’ll start with fats. Coconut oil for high heat cooking and olive oil for low heat cooking. We’re starting to accept the myth that saturated fats are bad was just wrong. They’re stable and hold up well to high heat, if your oil is smoking throw it out.

As a questionable runner up I’ll mention Canola oil. It’s low in Omega-6 fats but it’s heavily processed. You get olive oil by squeezing the olives, the process for canola oil is a bit more complicated.

For protein, meat’s important but most of us eat too much of it. Organic makes a lot more sense here as you’re higher up the food chain but it can get expensive.

We’ve been ingrained with the belief that processed foods are bad, but the positive approach is to aim for high nutritional density. Kale gets it’s great reputation because it’s at the top when compared this way.

Eggs got a bad wrap, they truly are a super food. Most of the cholesterol in our blood is made by our body. A far more important indicator is the ratio between the types and densities of cholesterol.

I can always judge how well I’m eating when I’m standing at the checkout lane at the supermarket. The basic idea with shopping is to mostly buy from the perimeter of the store.

What we don’t see when we buy our food is all of the bugs in it. We’ve become a germ phobic society but only 10 percent of the cells in the body are human. I like the quote that antibiotics were the science of the 20th century while probiotics will be the science of the 21st century.

It’s good to eat your vegetables with meals raw, cooked and fermented. Raw sauerkraut and pickles are a great source of natural probiotics.

With fiber it’s important to note the difference between soluble and insoluble fiber, the former slowing you down while the latter speeds you up. Psyllium seed powder is a great natural form of soluble fiber.

Two common food triggers to watch out for are gluten and dairy. The best way to check for a sensitivity is to eliminate it for 30 days and then add it back for a few days in a row.

The trouble with gluten is more accurately an issue with Zonulin (sounds like a bad guy from a Superman comic) which can loosen the gut lining.

Most people can digest dairy when younger but many lose the ability as they get older. It’s akin to losing our hearing as we get older but digestive health and genetics plays a role.

Bone broth soup is one of the single best foods you can eat. Some frozen veg (brocoli, colifower, carrots, etc) boiled in broth and then pureed with a hand mixer makes a great soup. Maybe add a bit of coconut milk and some salt & pepper.

Create object in JavaScript using named parameters

The following code should look familiar, we’re creating an object and assigning a property.

function Person(id) {
	var self = this;
	self.id = id;
}

var instance = new Person(1);

One challenge with this approach is that as you add properties remembering their order can become a mental task.

function Person(id, firstName, lastName, phoneNumber) {
	var self = this;
	self.id = id;
	self.firstName = firstName;
	self.lastName = lastName;
	self.phoneNumber = phoneNumber;
}

var instance = new Person(1, 'Bill', 'Gates', '212-555-1234');

An alternate approach to consider is to use jQuery’s extend function (or Underscore, AngularJS, etc) which enables passing named parameters.

function Person(data) {
	var self = this;
	$.extend(self, data);
}

var instance = new Person({
	id: 1,
	firstName: 'Bill',
	lastName: 'Gates',
	phoneNumber: '212-555-1234'
});

A nice by-product of this approach is that it makes it simple to serialize/de-serialize the object, for example to store it to Local Storage.

var jsonString = JSON.stringify(instance);
// write to storage
// ...
// read from storage
var instance = new Person(JSON.parse(jsonString));

Setting Facebook meta tags

A goal for many of the sites we build is for them to be shared on Facebook. The least we can do is make sure they look good when it happens.

The first thing you’ll want to do is run your site through the Facebook Debugger.

I’m currently setting this up for Invoice Ninja. You can see below what our site looked like before setting the meta tags. In the “Open Graph Warnings That Should Be Fixed” section there are a number of properties which are inferred.

Facebook Debugger

To set the metadata (and resolved the warnings) you just need to add the following meta tags to the website, filling in your own values for the content fields.

<meta property="og:url" content=""></meta>
<meta property="og:title" content=""></meta>
<meta property="og:image" content=""></meta>
<meta property="og:description" content=""></meta>

It’s worth noting that after your site gets 50 likes the title becomes fixed.

For a listing of all available tags and options check out the Open Graph documentation at http://ogp.me/.

Friendly URLs with per-account incrementing Ids in Laravel

For Invoice Ninja we wanted each account to be able to use friendly URLs where their Ids would increment.

This would mean the URL for the first client they create would be https://www.invoiceninja.com/clients/1

Many accounts are stored in the same database so we’re not able to use the auto-incrementing Id field. The solution we’re using is to have all classes which store user data (ie, clients, invoices, payments, etc) extend the EntityModel class. To create a new instance you call the createNew() method.

Here are the benefits of this approach:

  • Context is tracked: The account and user the record belong to is automatically set. If an item is created by the system (ie, an automatically sent recurring invoice) the context can be inherited from an existing record.
  • Out of the box security: When setting foreign key values we use getPrivateId() to resolve the public id to a private table Id. This prevents the user from hand modifying the HTML to reference another account’s data.
  • Easy scoping: Using the scope() method we’re able to easily load data filtered by the account. For example Client::scope()->get() returns all of the accounts clients, while Client::scope($publicId)->get() returns a client using its public Id.

And finally the code…

class EntityModel extends Eloquent
{
	protected $softDelete = true;
	public $timestamps = true;
	
	protected $hidden = ['id', 'created_at', 'deleted_at', 'updated_at'];

	public static function createNew($parent = false)
	{		
		$className = get_called_class();
		$entity = new $className();
		
		if ($parent) 
		{
			$entity->user_id = $parent->user_id;
			$entity->account_id = $parent->account_id;
		} 
		else if (Auth::check()) 
		{
			$entity->user_id = Auth::user()->id;
			$entity->account_id = Auth::user()->account_id;			
		} 
		else 
		{
			Utils::fatalError();
		}

		$lastEntity = $className::withTrashed()->scope(false, $entity->account_id)->orderBy('public_id', 'DESC')->first();

		if ($lastEntity)
		{
			$entity->public_id = $lastEntity->public_id + 1;
		}
		else
		{
			$entity->public_id = 1;
		}
		
		return $entity;
	}

	public static function getPrivateId($publicId)
	{
		$className = get_called_class();
		return $className::scope($publicId)->pluck('id');
	}

	public function scopeScope($query, $publicId = false, $accountId = false)
	{
		if (!$accountId) 
		{
			$accountId = Auth::user()->account_id;
		}
		
		$query->whereAccountId($accountId);

		if ($publicId)
		{
			if (is_array($publicId))
			{
				$query->whereIn('public_id', $publicId);
			}
			else
			{
				$query->wherePublicId($publicId);
			}
		}
		
		return $query;
	}
}

I’m sure there are other ways to tackle this problem. Let me know in the comments or on twitter @hillelcoren if you have a different solution.

Logging errors in Laravel

Laravel comes with a really helpful Log::error() function to write messages to the log file. Here’s how you can use it to track PHP and JavaScript errors along with useful contextual information to help troubleshoot problems.

The Log::error() function accepts a second optional parameter allowing you to specify additional info. To make setting this easier create a logError() function in a Utils class.

public static function logError($error, $code = '', $context = 'PHP')
{
	$count = Session::get('error_count', 0);
	Session::put('error_count', ++$count);

	$data = [
		'context' => $context,
		'user_id' => Auth::check() ? Auth::user()->id : 0,
		'user_name' => Auth::check() ? Auth::user()->getDisplayName() : '',
		'url' => Request::url(),
		'user_agent' => isset($_SERVER['HTTP_USER_AGENT']) ? $_SERVER['HTTP_USER_AGENT'] : '',
		'ip' => Request::getClientIp(),
		'count' => $count,
		'code' => $code
	];

	Log::error($error, $data);
}

Most of the code should be self explanatory. getDisplayName() is a function I add to the User class (as well as other classes) where there is logic involved in determining the name. In this case it may be the user’s full name or email address.

To configure Laravel to use this function by default change the App::error() function in app/start/global.php to the following.

App::error(function(Exception $exception, $code)
{
	Utils::logError($exception, $code);
});

To catch all JavaScript errors enable accessing the Utils::logError() function by adding this to your routes.php file.

Route::get('/log_error', function() 
{
	return Utils::logError(Input::get('error'), '', 'JavaScript');
});

And finally, add the following to function to your master template file.

window.onerror = function(e) {
	try {
		$.ajax({
			type: 'GET',
			url: '{{ URL::to('log_error') }}',
			data: 'error='+e
		});     
	} catch(err) {}
	return false;
}

The future of web development is Laravel

PHP is an old friend, going back close to 15 years. It was the first language I used. Back then it was the obvious choice for web development if you were running Linux/Apache, it was free and it was popular.

Over the years other languages/frameworks have appeared which have definitely captured the “cool” factor. The two obvious ones are Ruby on Rails and Python/Django. It’s possible to argue that Ruby and Python are more aesthetically pleasing languages to code in but their real draws are the MVC implementations of Rails and Django.

From a business stand point PHP makes a lot of sense. The more recent versions are dramatically improved and it’s incredibly well supported. There are far more PHP developers which helps keep costs down and it scales. If it’s good enough for Facebook chances are it’s good enough for you.

The challenge has always been finding the right MVC framework. Laravel solves this problem. It provides a best-in-class MVC implementation for PHP.

Reading the tea leaves it’s clear that I’m not the only one who feels this way. This is from Google Trends and leanpub.com. It feels good to be excited about PHP again.

As a side note, using puPHPet, Vagrant and VirtualBox to create virtual machines to play with Laravel makes me feel like a programming super hero with the power to create worlds.

The iOS7-ification of an app

iOS7 has gotten rid of button borders. While the lists and table views in my latest iPhone app converted automatically, I ran into a problem with the main UI as it’s made up entirely of buttons.

To get a flat iOS7 looking UI while still retaining the button backgrounds I used the excellent FlatUIKit collection of components.

Here’s a comparison of the iOS6 and iOS7 versions of the app.

mscmkr

Follow

Get every new post delivered to your Inbox.

Join 86 other followers

%d bloggers like this: