January 19, 2012 § Leave a comment
PayPal can be a pain in the butt to integrate in with your website. I sit next the guy on our team tasked with doing PayPal integration. I swear I can see the wrinkles and gray hair starting in on him. One of the biggest pains you’ll run into is testing the callbacks and web hooks. If you are doing anything more than putting a little donate button on you site, you’ll be dealing with IPN callbacks to keep your database in sync with PayPal. Typically your doing your development on a local machine that isn’t exposed to the outside world so you can’t have them post directly your dev machine. Bummer. There are a number of ways one can go about dealing with, I’ll mention two that we have tried before we found the third.
Test it on Prod
Nothing ever goes wrong when you do this right? A better solution here is to set up a separate staging machine that is hooked up to the PayPal sandbox, but setting up boxes just to do some sporadic testing really sucks. What if there was a service you could just point PayPal at to and just showed you what PayPal was posting, would that be better?
postbin.org is a nice little service that provides web hook endpoints. It’ll give you a url to give PayPal as a callback url. When PayPal post to this url you’ll be able to inspect the request it sends. Unfortunately you’ll then have to manually parse it and figure out a way to post that info locally on your machine. But hey, no extra machines floating around in your cloud just wasting space and money! But there still has to be a better way to do this. I really would rather all of this just go to my local dev machine. Please tell me this can be done!
Enter localtunnel. localtunnel is a ruby gem that does what the name implies. It hooks your local server up to the world wide web by tunneling to a subdomain of localtunnel.com. You simply install and run the gem giving it your public key and a port and BOOM.
http://as2js.localtunnel.com now points to your local dev machine. The PayPal IPN’s can now trigger all that nice sync code you have written.
I am currently working on some GitHub continuous integration web hook stuff, so this tool has been invaluable. Priceless even. The only additional thing I would like to see with this gem would be a way to deploy the server side to your own machine. While localtunnel.com is fine and dandy, I’d feel better if I controlled all the stops of the data. Anyways, get you localtunnel up and you web hooks on!
December 29, 2011 § Leave a comment
Note: I wrote this up a few weeks a go, but didn’t publish it for some reason. It is a touch out of date since Rails 3.2 RC1 was recently released, but should be close enough to give you a good idea on how to get up and running on Rails master.
I wanted to play with the latest and greatest for Rails, which at the time of writing is 3.2.0.beta (RC 1 is now out). This means building and installing the rails gem locally. It took me a good while to figure out how to get everything working, so I figured I’d throw it down here for future reference… and for anyone else running into the same problems I did.
I am using rvm to isolate my different gem set ups, so as not to get random version conflicts. These are the lists of commands with notes I ran to get everything up and running:
# create a new gemset to use with rails master rvm gemset create rails-master rvm gemset use rails-master # this is where I am going to put all of the git repos cd ~/src # Rails 3.2.0.beta requires the most recent (as in master) # versions of arel and journey git clone git://github.com/rails/arel.git cd arel gem build arel.gemspec gem install arel-*.gem cd .. git clone git://github.com/rails/journey.git cd journey gem build journey.gemspec gem install journey-*.gem # now get Rails cd .. git clone git://github.com/rails/rails.git cd rails # install all of the Rails pieces, # i.e., ActiveRecord, ActiveSupport, etc... cat RAILS_VERSION | xargs ruby install.rb # check to make sure you are riding the correct rails ruby -r 'rails' -e 'puts Rails::VERSION::STRING'
You can get just the commands in a gist too.
December 27, 2011 § 1 Comment
Rails 3.2 RC1 was released last week and it announces some pretty cool new things. One of those things is something that I have played with building out myself (tagged logging) and another is something I actually did (ActiveRecord Store). When I wrote my data-attributes gem, I was inspired to do so because I had a users table that had an ever-growing number of email permission checks. I never queried against these, and they made doing a
SELCET * FROM users; really painful to try and read. I decided to just throw them all in a serialized column and be done with it.
When I first read the release notes for 3.2 I had two thoughts go through my head.
1) Well, crap.
data-attributes is now dead and useless. (yes, I use <code> tags in my head)
2) Awesome, the solution I came up with for a problem I was having is the same one that the Rails team came up with. Maybe I might know a thing or two about what I am doing.
But as I started to compare the new ActiveRecord::Store with
data-attributes, I began to realize that my little project isn’t dead quite yet. The accessors generated by the store call with AR::S aren’t full attribute accessors. By this I mean they don’t go through
write_attribute before committing the new data to the serialized hash. This prevents you from intercepting the accessor call and doing some pre/post processing. You also don’t get default values as with other attribute accessors. Definitely not a huge deal in the least, but something to be aware of. AR::S does mark things as dirty though.
data-attributes does not do this as of yet.
As for the future for of
data-attributes, I think that it is actually dead in the long run. If I were to work on this problem more in the future, I’d probably do so by adding the AR::S instead of continuing working on
November 1, 2011 § Leave a comment
One doesn’t go through the process of starting a new ruby gem all that often. Even if you have published a few, it is easy to forget how get one started. So here, for my benefit as much as anyone else’s, is a quick easy way to get a gem started and hosted on GitHub.
On the command line navigate to the directory you want to use to work on your different gems.
> cd ~/Projects/gems
I like using bundler, so this is what I do:
> bundle gem <gem name> create <gem name>/Gemfile create <gem name>/Rakefile create <gem name>/.gitignore create <gem name>/.gemspec create <gem name>/lib/<gem name>.rb create <gem name>/lib/<gem name>/version.rb
It will create a directory for you with the gem name and initialize a git repo for you with everything already staged to be committed. Now you need to create a new repo on GitHub. It’s pretty straight forward, so I’ll let GitHub’s on screen instructions take it from there. My only suggestion would be to make the project name the same as your gem name to avoid confusion.
Note: If you use dashes “-” instead of underscores “_” in your gem name, bundler will treat them as module hierarchies and build folders to accomodate.
Now cd into your new gem’s directory.
> cd <gem name>
Hook the git repo up with GitHub. The link should be shown on the empty repo’s main page. Just copy that.
> git remote add origin firstname.lastname@example.org:<GitHub username>/<GitHub Project Name>.git
Now commit your skeleton. Everything is already staged for you.
> git commit -m "Initial commit"
Now push it out to GitHub
> git push origin master
And just like that you are ready to start working on your new ruby gem. You’ll also want to remember the following commands:
> rake build # build <gem name>-<version> into pkg directory > rake install # build and install <gem name>-<version> on local machine > rake release # tags the repo with the version number and pushes new version out to RubyGems.org
Google will be able to tell you more about filling out the .gemspec file than I can. This is just to get you up and running.
October 18, 2011 § Leave a comment
A while ago I was working on a web app built on Rails that needed some very basic tag analysis. Having once upon a time obtained a MS in Computational Mathematics I will always view tags as a big matrix. A big, sparse matrix with tag names along one dimension and the objects being tagged along the other. When you think about tags like this all kinds of avenues of analysis open up.
You can think of objects as tag vectors (or tags as object vectors) with non-zero entries representing the tags on an object. By multiplying two tag vectors together you get the dot product (or cosine similarity) of the two vectors. This a nice rough estimate of how similar two objects are with respect to their given tags. Multiplying a tag vector (a.k.a. the query vector) with whole matrix will find you the most similar objects (or tags). Math is fun!
To this end I started poking around trying to find a sparse matrix library written for ruby to make my life easier. Alas, no glory. Now I know that Ruby doesn’t have the same math support that, say python has, but I would have thought someone would have thrown something usable together.
I ended up hacking together a very basic SparseVector class to take care of my immediate needs, but felt that there was a chance to create something new for the community. I looked at things like LAPACK ruby binding and NArray, but these all dealt with dense matrices. My data was incredibly sparse, so they didn’t really cut it. With that said, I have been working on a sparse matrix gem. It’s a pure ruby implementation, so it should be nice and portable and good enough for small prototypes and datasets. I wanted it to be in Ruby so that I could subclass it off of the standard library Matrix class and have it run anywhere Ruby runs. Not having any bindings to compile is a plus for me, since it means I don’t have to worry about the different environments it might be running in. If you are working with really large datasets then this probably isn’t for you right now.
Check out my progress over on GitHub.
July 28, 2011 § Leave a comment
Dealing with dates is hard. Dealing date calculations is harder. Luckily, in the Rails world we have ActiveSupport to help us with a lot of this. It actually does so much, that I usually forget how much of a pain dealing with dates is suppose to be. However, there are times now and then that I am reminded. Little edge cases that haven’t yet been built into ActiveSupport. One such edge case is determining the number of months between two dates. Why do months have to have different numbers of days?
This particular use case can be very useful when dealing with recurring payments. Calculating the number of payment cycles a subscriber has gone through can tell you how much revenue they have generated. I have put together two class methods for the Time object that will calculate just this. One is a simple loop that takes time proportional to the time between the start and end times, and the other a more efficient direct calculation of the same number.
The simple loop looks like:
def months_between2(start_date, end_date) return -months_between2(end_date, start_date) if end_date < start_date count = 1 while true return count - 1 if (start_date + count.months) > end_date count += 1 end end
It just starts at the
start_date and keeps adding months until it passes the
end_date. Not particularly difficult, but should get the job done for most cases. All the complexity of the more efficient version comes from checks dealing with the various cases arising from different months having a different number of days. Anyways, the source code for that one looks much nicer over on GitHub.
July 21, 2011 § Leave a comment
In computer programs, number constants can be interesting and bewildering things. Trying to figure out why one was chosen over another can be really confusing. For a good while I was confused as to why ActiveRecord would set a string attribute to be a VARCHAR(255) in the database. It limits the size of the string attributes to 255 characters long. 256 is a bit more natural when choosing constants in computer science. 255 is commonly used to denoted the last index in a 0-based array of 256 elements. So why 255? The short answer is “because of InnoDB and UTF-8 character sets.”
InnoDB has a limitation on the size of a key for a single column index of 767 bytes. When the table is encoded with a UTF-8 character set, each characters has the possibility of using 3-bytes to represent its intended character. That means in order to be able to fully index a UTF-8 encoded varchar column, the string must be able to be represented in 767 bytes. 767 / 3 = 255 2/3. This means that the largest UTF-8 encoded varchar column can be 255 characters long, hence the ActiveRecord default string attribute size.
Problems on the Way
As bigger and bigger pushes are made for complete internationalization, we’ll see more things encoded with UTF-16 and UTF-32. Characters using these encodings might require up to 4 bytes to represent their value. When this happens, ActiveRecord will need to reduce the size of indexable string attributes to 191 characters.
Here is a truly awesome magic number that seems to come out of no where, 0x5f3759d5.