find_each, not all
This great presentation at RailsConf 2012 by James Edward Grey II pointed out something I hadn’t taken into account. This:
User.all do |user|
# do something...
end
is bad mojo for potential large tables because it will attempt to load the entire table into memory. A better habit to get into is:
User.find_each do |user|
# do something...
end
This will have the same net result, but it will only pull 1000 records at a time into memory.
- parkerSilence!
As great as the Rails asset pipeline is, I don’t understand the need for it to punish your log with overly-verbose output. Why not only only log missed assets? Why must I be told on every request that all 13 stylesheets/javascripts were fetched? Moreover, why doesn’t Rails itself provide a simple way to turn this off? Nevertheless, a gem exists to do just that:
gem 'quiet_assets'
Boom.
- parkerGit auto-complete
I’ve recently become a big fan of using git branches more regularly in my coding. My biggest frustration was the internal struggle between descriptive branch names and having to remember/type it every time I needed to make a small change in master. Enter git auto-complete:
http://www.codethatmatters.com/2010/01/git-autocomplete-in-mac-os-x/
Works great.
- parkerRails questions for Node.js
I don’t want to jump to conclusions, but after hours and hours of researching Node.js, all I hear is, “It’s fast.” Well, thats great, except that people are also saying it’s the “new Rails.” I’ve got a few questions regarding that claim and encourage any Node.js fan to send me answers to adam@mysterioustrousers.com and I will post the best answers below each question. Thanks.
Can one reasonably argue that you could make an equally complex app in Node.js as fast as you could with Rails?
In my opinion, the best thing about Rails is how structured it is. It almost makes it impossible for anyone to screw up a Rails app. They are all structured the same because of DHH’s quoting “A place for everything and everything in its place”. I can open any Rails app and instantly know where i can find almost anything. Rails apps almost force me to write well structured code. How is Node.js any better at this than PHP without the cake?
Rails is full of time saving development goodness like generators, migrations, etc to help cut down on developer hassle and billing time. Is Node.js concerned with developer happiness and billing time at all (Hackers are usually oblivious to the business concerns of a project)?
IF you cannot argue that 1) Node.js is just as fast to develop with as Rails, 2) Node.js makes it easy for developers to write clean code and 3) Node.js cuts down on dev hassle and billing time more than any PHP, then my last question is this: If the average programmer is $40/hr and the average server is $0.05/hr, why does it matter if Node.js can handle as much as a Rails app on half or even 1/10 as many servers, if it takes even a few hours more to develop/maintain with Node.js than Rails?
Rails is awesome only slightly because of the Ruby language, it’s the framework itself that makes working with it fun. Until there is a framework around Node.js that makes web development as fun and fast as Rails does…I just don’t get it.
- adamSyncing iCloud iWork docs to your Mac
It’s a piece of cake to sync your pages, keynote and numbers docs between your iOS devices, but what about the Mac? I’ve been trying to do this for months. Well, if you’ve ever wanted to as well, take a look in ~/Library/Mobile Documents.
- adamHirb Gem
Super rad gem for displaying query results in the rails console https://github.com/cldwalker/hirb
- adamSetting up Braintree in Rails
add the gem http://cl.ly/3M0j3X3R1A2X2Q1i2T2I
add the initializer
set up an “after_create” on whatever you’re tying the credit cards to and add them to braintree as a customer when its created http://cl.ly/062C3K1V0r2j1R1s3p0f
create a credit card model (only store masked cc #) http://cl.ly/1A3r260e2c3B2m21071d
recap: create a customer, create a credit card attached to that customer, charge the card.
when you create a customer or card, you have to pass it in a id/token that you generate yourself
when you create the credit card, you pass in the token you generated for the customer
when you charge the credit card, you pass the token you created for the card
heres the credit card table migration http://cl.ly/0930292B432f0j320a3A
- adamIBOutlets/IBActions
Maybe this is common knowledge, maybe not, but I found it interesting. IBActions and IBOutlets don’t have to be in the header file. You can put them in the category extension in the implementation file and everything will still work as it would if placed in the header. Makes for clean uncluttered headers with only the relevant public properties and methods.
Also in Interface Builder there is a handy little trick you can do to automatically create the IBAction/IBOutlet properties and methods…simply control-click-drag from the UI element directly to the category extension in the implementation file. Maybe it’s a little over the top but kind of cool anyway.
- jamesCalvetica 4.3
Because of the iOS 5 only features we want to add, and also the iOS 5 SDK changes to view controllers that Dan pointed out, we’re going to make Calv 4.3 iOS 5 only. We’re getting rid of support for iOS 4. It’s been long enough since 5 was released and there is no way we’re going to clutter our code with hacks so that the view controllers work correctly on 4 and 5.
- adamSublime Text 2
This is getting some press lately, some claiming it superior to TextMate, as well as more active development. All I care about is Vintage mode for emulating Vim keybindings. Huzzah! I may finally have a reason to switch away from my beloved MacVim.
- parkerTextmate 2.0 looks awesome
Favorite thing so far: the new file browser. Very clean, cool shortcut buttons and you can drag and drop to move files…very nice.
- adambackground execution and main thread
If you perform a task on a thread in the background (after the app has gone inactive) and then add an execution block to the main threads queue, while still in the background, it will not start executing until the app becomes active again.
This is why I cannot completely reload dialvetica as the app goes inactive, I can only do the background processing part, the table has to be reloaded when the app becomes active.
- adamHeads up on ios 5 view controllers
http://gamesfromwithin.com/view-controller-notification-changes-on-ios5
Copy and paste this one into browser if it doesn’t work
- danMediaPlayer framework bugs
There are a few bugs in the MediaPlayer framework that are not well documented anywhere and can be challenging to recognize/fix.
1) MPMusicPlaybackState is not always correct. The most common inconsistency I’ve seen with is that is reports a Paused state when it’s actually Playing(Most often on iPad). I was able to come up with a workaround for this that has been more reliable:
float time1 = playbackTime
BOOL playing = playbackState
float time2 = playbackTime
if (playing == YES) return playing : otherwise return (time2 > time1)
Let me know if anybody has a better way of doing this.
2) MPMediaItemPropertyPredicate/MPMediaQuery approach to searching for an MPMediaItem doesn’t always work. It seems to fail most frequently/randomly if you are searching for the current playing item. I created a 3 deep search for items that has been much more reliable(you’ll have to persist the persistentID and a few other properties):
search using the regular persistentID
if not found
search using a custom id comprised of the albumTitle, artist, title, albumTrackNumber
if not found
compare it to the current playing item
if found return the current playing item
3) The MPMusicPlayerControllerNowPlayingItemDidChangeNotification is sometimes randomly posted twice. Seems to happen most often when playing a new MPMediaItem/MPMediaItemCollection. Depending on how you handle the notification you may need to compensate for the *extra* notification
4) persistentID(unsigned long long NSNumber) has issues with memory overflow if you try to persist it. As a workaround convert it to NSString to persist and then back to an unsigned long long when you need to compare it to the original NSNumber
As far as bugs go those are the biggest/most frequent that i have encountered. Also the framework is riddled with valueForProperty calls that you have to remember, I found it very useful to create a category on MPMediaItem and MPMediaPlaylist and made methods for each of the valueForProperty calls. example [item artist] is much cleaner than [item valueForProperty:MPMediaItemPropertyArtist]. I took a similar approach with getting properties for the music player
Hopefully this will help somebody someday
- jamesKickoff App
We’re switching from Flow to Kickoff as our task manager.
Flow pros: - Super cool and easy task addition - Web app, mac app and iOS app (all are very nicely built) - Pretty darn good UI - Not buggy at all - notifications are awesome and very informative. You never miss anything.
Flow cons: - tags are private to individual users (WTF???) - how you organize lists into folders is private to users (W….T…F…!!!!!!!!) - Managing all the fine grained permissions is a freaking PAIN for small teams where we’d rather everyone just have access to everything. - PRICEY!!!
Kickoff pros: - The mac app is fully featured and fast - Super simple tasks, easy to add tasks - No complex permissions - Quite affordable - AWESOME meeting room chat. SO FREAKING USEFUL. - fixes pretty much everything we hate about
Kickoff cons: - no tags on tasks - a little buggy. When I want to see one users tasks across all lists, it doesn’t work. Among other little things. - The dashboard doesn’t show when people leave comments so no one notices
Overall, we like the simplicity of Kickoff more and we’ve emailed them and they say they are gonna remove the cons I’ve listed, so we’re super excited about it.
- adam