I’ve mostly been using Siggnal on my iPad, which doesn’t seem to keep, or at least, share cookies as liberally. Consequence being that I had to log in to Twitter OAuth every time (on an iPad touch keyboard no less) I changed the user id store to store for two weeks, rather than the browser session.
Stomping the N+1
Glancing at the log, I had noticed that the feed view was doing an N+1 query – for every tweet received, it was doing a database lookup to see if it had been previously voted upon. I collected all the ids, and used
where :id => array to generate a
WHERE id IN clause.
Doing things the rails way
A little while ago I got The Rails 3 Way. It’s organized more as a reference, but I found a number of things I could be doing better. I had found a way to get JSON out of Rails, but had missed
to_json. Using that method meant I couldn’t bury
html_safe in my own method, but it may be better to be explicit anyway. I had the opposite issue with
auto_link, which replaced my own add-hoc method, but required me to explicitly
h html-escape the parameter (a win for the test suite)
Not taking the scenic route
Another trick was scoped routes. Since my main url scheme so far involves aping the external services, there is a somewhat haphazard collection of urls under twitter. Scoped routes allowed me to put most of those under
namespace :twitter and avoid repeating it every time.
The Rails 3 Way was also another vote in favor of Decent Exposure, a gem I’d already had my eye on. Decent exposure streamlines the process of creating helper methods, so that views call a method (which can be easily substituted for a variable in partials) instead of referencing instance variables, a process which surely involves a bit of black magic. Having to name these methods at the controller level also helps provide better names – I had a few too many
@results before the conversion.
Of course the MVC purists cry in horror that you have views triggering database queries. I’m not sure I subscribe to the idea that a controller action dwindles to nothing – I’m usually calling respond_with using the primary helper method so there is data for other formats (though I’m not sure I support any other formats yet)
What a Ham
A little later one, I also converted most pages to HAML. HAML is a more concise syntax for specifying HTML rails views. Since it is indentation based, I had to add a few levels of indentation to some of my pages. It also requires newlines to be escaped for ruby code, which has the practical effect of forcing any code into helpers, which appears to be deliberate.
With the instance variables cleaned up, I turned my attention to the critical feature of a minimum-viable-product (MVP) : getting paid. In order to do that, I had to have some place to put the payment request. (Of course, I still need to put it lots of places – it’s still a bit hidden) For this I built a users controller, with just a show action, so that a user could see their account status and upgrade to a paid account.
The Payment Jungle
There are a lot of payment systems out there. I was attracted to systems like Chargify and Recurly that handle everything for your, but they all expect a monthly service charge up front. I can’t blame them – I’m doing something similar, albeit with some level of free service. I also don’t want to get hooked into paying for services when I haven’t proven that anyone will pay for my service. So, Paypal it was.
Even Paypal had a plethora of options – there are website payments standard, pro, adaptive payment api, and more besides. In the spirit of MVP, I’m starting with a basic pay button. Actually crediting a user’s account will be a manual process until I start getting enough registrations that it actually becomes burdensome.
The trick, of course, is figuring out who to credit. After poking around a bit, and running some experiments against the sandbox, I figured out that the
custom field does show on received payments.
The sandbox made testing practical. It’s an interesting affair where you have to be logged into a developer account, at which point you can create fake buyer and seller accounts. The sandbox is still single-signin, so buying something and then flipping over to the seller is a little annoying. A multiple-clipboard tool helped keep me from getting too frustrated.
In order to make purchases viable, I had to have some way to mark paid users. Up til now I had hard-coded my own account name into the token permission system. Thus the user model got it’s first field, an expiration date. Ideally there would be a payments table of some sort so I can regenerate permissions against any future payment models, but that’s hardly necessary if I have no payments.
Initially I protected user pages, and set up the buttons to credit the currently logged in user. I then realized that was a little odd, given they were on a specific user’s page. I opened up user pages and attributed the user, so gifting is possible. However, there isn’t a way to find a user’s page, just a layout link to the currently logged in user.
There is, however, now a Followcost-style account lookup on the front page to get a user’s rating (which practically speaking, means what I think of them) The account page also includes a miniature siggnal-to-noise graph to give a more visual indication.
I mentioned Siggnal on Twitter and apparently got a visitor or two. At the time I didn’t really have any way to get feedback. There are number of services that focus on collecting and filtering user feedback. A couple of them have free starter plans. I actually signed up with Get Satisfaction before I signed out and realized that they require you to be signed into their service. At this point I want all the feedback I can get, so such friction doesn’t serve my purposes.
After searching around a bit, I found Plupper, which has a free service with relatively inexpensive growth. This is reflected in the quality – I ran into one bug right off. Plupper main thrust seems to be real-time chat, but I haven’t been hanging out on IRC in years and don’t expect Siggnal is getting all that much traffic. However, the other feedback features don’t seem to work with the chat option disabled.