Postgres and Grape::Entities: Decimals appear as strings

Sometimes grape-entity needs a little help figuring out the correct data type for model attributes. Take the following example, when using PostgreSQL as the backing DB :cost is returned as a (string)”10.5″ instead of the (float)10.5. Although you could handle this fairly quickly on the UI side (new Number() comes to mind) it’s better to return the correct data types in the API.

[code lang=”ruby”]
class Foo < ActiveRecord::Base
// cost :decimal(6, 2)
end

class FooEntity < Grape::Entity
expose :cost
end

// GET /foos/1
// { cost: "10.5" }
[/code]

So why does this happen? It’s all about printing objects. PostgreSQL returns decimals as BigInteger objects instead of native floats. This causes grape-entity to output the BigDecimal object using to_s.

Getting around this is fairly simple though. By overriding the :cost attribute we can coerce our :cost attribute into a float.

[code lang=”ruby”]
class FooEntity < Grape::Entity
expose :cost
def cost
object.cost.to_f
end
end

// GET /foos/1
// { cost: 10.5 }
[/code]

P.S. If you’re a fan of grape and haven’t tried out grape-entity you’re missing out! It’s a great way of creating reusable object definitions when outputting data from your grape-based APIs.

Rails: ParamsWrapper

Recently I stumbled onto the ParamsWrapper system inside of Rails. It’s a convenient system that allows form data to be submitted without specifying the root object. For example, if you are creating a new post you can specify the name using either name=”name” or name=”post[name]”. Either way you can access the attribute using params[:post][:name].

Most of the time the system works perfectly without modification. It uses the model represented by the controller’s attr_accessor definition to determine which attributes work. However if you are not using the rails preferred naming scheme this system may no longer work as expected.

For example, let’s create a User model and a RegistrationController

[code language=”ruby”]
class User < ActiveRecord::Base
attr_accessor :name, :email
end

class RegistrationController < ApplicationController
def create
User.create params[:user]
end
end
[/code]

And a form to create the user

[code lang=”html”]
<%= form_for @user do %>
<input name="name" type="text" />
<input name="email" type="email" />
<% end %>
[/code]

Now since we can usually rely on ParamsWrapper the above code would work. However since we’ve named our controller registrations we can no longer guarantee the users parameters will exist in params[:user]. We can however fix this by calling the wrap_parameters method on the controller.

[code language=”ruby”]
class RegistrationController < ApplicationController
wrap_parameters User

def create
User.create params[:user]
end
end
[/code]

Take notice we specify the model using the class and not a symbol. By using the class the models class will be used to determine what attributes to place in the params[:user] hash. If a symbol is specified all attributes passed in will be placed into the hash.

RubyMine: Updating to Rails 4

Recently I spent some time upgrading one of my rails projects from Rails3 to Rails4. Among other resources Episode #415 from RailsCasts helped tremendously. However one of the issues that were not covered was fixing some of the issues with RubyMine integrations, more specifically the “Rails 3.x launcher script was found instead of Rails 4.x one”.

The easiest way I’ve found to address the issue is simply create a new rails 4 project and copy the bin/ directory that is created into your upgraded rails project. This doesn’t seem to me to be the cleanest solution but it does appear to be effective. Upon closer examination of the scripts in bin/ none of them appear to be project or even version specific. There are three scripts that is created: bundle, rails and rake.

The same error is produced even when attempting to run Rails 3 projects. Due to the way the new bin/ scripts were made they are also compatible with Rails3 projects. Performing the same copy solution above to your Rails 3 project will get RubyMine working again for you.

Pandora on Android – Service starting automatically

For the past few weeks I’ve been having problems with my original Droid. After using an app, switching back to the home screen always caused ADW to reload. At first it didn’t really bother me, I figured it just needed to be rebooted so I rebooted it and continued on my way.

Fast forward to now. My Droid has been almost unusable. Even the dialer app was beginning to freeze. I had installed Lookout Mobile Security a while back so I figured it was the culprit so I uninstalled it.

Although removing Lookout helped, it didn’t solve the problem. The phone was still locking up with everything I did. To help me with my problem I went to ATK to figure out what was happening. Using ATK to kill a few apps seemed to solve the problem. My Droid was back up ready for action.

However it wasn’t long before the slowness came back. I decided to start killing off apps one by one to figure out which one was causing my problem. Each time I opened ATK I kept noticing Pandora was running in the background even though I hadn’t opened the app in the last month.

Over the next day I kept killing off Pandora over and over again. Sometimes it would remain off for a few hours other times it started immediately after killing it. So I opened up the app to determine if one of its settings was causing it to automatically start.

Looking through the settings I found only one setting that was switched to “on”, Bluetooth for Automotive. Turning off this option stopped Pandora from automatically starting as a service.

My phone has been working great every since. No more slowness issues (at least not anymore then when I first got it) and I can open apps again without killing ADW.

As apps continue to advance so do their hardware requirements. Pandora is still a great app and I’m so glad I figured out what was causing my problems. Hopefully in the future changes such as these will be better conveyed to the end user. Listen on!

PHP Sessions Explained

Introduction
One of the most common requirements for any web application are sessions. Sessions are used to maintain information about a user on the server instead of using a cookies. Although session ids are stored in a cookie its considered more secure because a user cannot tamper with the contents of a session. If a user were to modify their session identifier PHP would just create a new session based on the new id.

Using Sessions
For each page that requires session data session_start() must be called. This causes PHP to read the users session id and load the data into RAM. Once loaded it is accessible via the $_SESSION super global array. From their you can modify the contents of $_SESSION.

Note: session_start() cannot be called once output has started.  A warning will be displayed and its possible the session could be lost.  If you are seeing the error “Cannot send session cache limiter” check to make sure no output is going to the browser.  A common problem is an unwanted space or tab at the outsize of the PHP tags.

Once you are done with a session you can call session_close() to force the modifications to the session to be saved. This is not required as PHP will automatically do this once the script ends.

The following is a short example of using a session.


Behind the Scenes
PHP makes using sessions easy, but what you don’t see is what its doing behind the scenes. The default PHP installation uses temporary files on the local disk for storing the session contents. When a session is started PHP will read the file which contains the serialized contents of $_SESSION. The data is unserialized and then placed in $_SESSION. When the session is closed, $_SESSION is serialized and stored in the temporary file.

The more unique hits you receive the more session files are created.  Allowing these files to buildup could cause problems on the web server.  It may run out of space, or you could hit the max file limit.  To prevent this from happening for each new session PHP runs a cleanup routine.  All session files that have timed out are removed from disk.

Custom Session Handlers
There is nothing to prevent you from making your own session handling system.  The PHP session handler is only provided as a convenience.  However before you “remake the wheel” you should consider overriding PHP’s session system using session_set_save_handler.  This allows you to override each of the six internal PHP session calls: open, close, read, write, destroy, and garbage collect.  Using this method you can create your own method of handling session data.

PHP’s documentation contains an example of how to use session_set_save_handler() here.

If you would like some more examples leave me a comment with what you would like to see.

Things to consider before outsourcing

Recently I had the advantage of exploring a side of programming that is becoming all the more popular in the business world of software development, Outsourcing.

Now at first outsourcing may sound like a great idea. Pay others to develop on your product without having to worry about hiring temporary employees. However, as easy as this sounds, there are some things you need to consider before you attempt to outsource your product. Continue reading “Things to consider before outsourcing”

SI Bowl 4×4 Beginners League

I want to compliment SI Bowl on the superb job they did at organizing the beginners 4×4 league. At $4 dollars p/night for 4 weeks and after successful completion receiving a free custom fit bowling ball, the league was surely a great deal!

Tonight was the final night for the league and we each received our new bowling balls (with the exception of back-ordered balls). It was awkward using the ball at first after being used to using the house balls. But after getting a feel for it I can definitely say having your own fitted ball is so much better than using the house balls.

Next week marks the start of the next league. This time we will all be working towards a free pair of bowling shoes. The game setup is also a little different, each night consisting of 3 games of 9-pin bowling for $7 dollars a night and running for 6 weeks.

Keep up the great promotions!