So far so good! 2
Couple days into playing with RubyCocoa and its so far so good! The toughest part of learning any new framework is learning the framework’s terminology and Cocoa’s no exception. Nibs, outlets, selectors, bindings… All foreign concepts if you’ve never worked in Cocoa before. Luckily the online tutorials are fairly good and Apple’s documentation is excellent.
The only problem i’ve run into so far turned out to be my own damned fault. I’m doing a lot of the RESTful heavy lifting using ActiveResource and it really doesn’t like receiving NSStrings as parameters. So much so that it crashes the App. No good. No good at all.
Remember kids, NSString != ruby string. to_s is your friend.
My jump into Cocoa programming 2
Ahh sweet freedom. After many months away taking care of things in the “Working World” I finally find myself with some extra time to pick up some projects to do on my own. My latest stint: Cocoa programming.
Granted I just started off, but right now the experience has been fantastic. The Cocoa architecture seems clean and well layed out, Interface Builder is fantastic to use (how much easier can you get then drag/drop and connect the pieces with lines?), and the best part… I don’t have to touch the icky language that is Obj-C. Yep, thanks to RubyCocoa I can do all the Mac development I want in the language of my choice.
I’ll post more as my experience grows!
ActsAsLocateable released 10
Introducing my 2nd adventure into Rails plugins: ActsAsLocateable!
ActsAsLocateable is an easy way to give any model the ability to be found by location. For instance, say you have a model Store which is associated with a zip code indicating where that Store is located. To find all the stores within a specific radius of another ZipCode, you can do a
Store.find_within_radius(10, 12345) # Find all stores within 10 miles of zip code 12345
Install ActsAsLocateable in the normal way
script/plugin install http://svn.baconbear.com/rails_plugins/acts_as_locateable/trunk/
Be sure to read the associated README file after the install for details on installation, setup, and usage.
ActsAsLocateable is based heavily on the ZipCodeSearch plugin by Doug Fales and utilizes much of the same code and data. Special thanks to Doug for making his code freely available!
VirtueDesktops: The new Virtual Desktop Manager in town 3
I’ve always been a fan of virtual desktops, dating way back to my PC days. Being able to organize desktops by work task has just been a huge time saver for me and really, I don’t know how I would work without one.
After using Desktop Manager on my Mac for the last 2 years or so, I recently found and switched over to using VirtueDesktops instead. Why? Number of reasons actually:
- Applications can be bound to a specific desktop. This means that when VirtueDesktops comes up, my Mail App is already on my “Mail” desktop, TextMate is already on my “Code” desktop, and Firefox is already on my “Web” desktop. This was something I had to do manually with Desktop Manager
- Clicking an Application on the dock automatically switches to the desktop that App is on.
- Actively developed. I haven’t seen a new version of Desktop Manager in over a year!
This is not to say VirtueDesktops isn’t without its flaws. I find it to be less stable then Desktop Manager, though its core functionality seems to be pretty solid. It’s little things such as text not updating, buttons not responding, and slightly inconsistent UI that tarnishes its otherwise excellent execution.
The latest version can be found here.
Found Feature: Nested Scopes 2
While browsing A Single Programmer’s Blog I came across this article regarding a little known Rails feature (at least to me) called “Nested Scope”
Ultimately it allows you to turn code like this:
def self.find_by_active_and_paying(options={})
conditions = Array.new
conditions << 'active = 1'
conditions << 'fee > 0'
conditions << options[:conditions]
self.find(:all, :conditions => [conditions.join(' AND '), options[:values])
end
Into this:
def self.find_by_active_and_paying(options={})
active_scope do
paying_scope do
self.find(:all, options)
end
end
end
protected
def self.active_scope
with_scope(:find => {:conditions => 'active = 1'}) do
yield
end
end
def self.paying_scope
with_scope(:find => {:conditions => 'fee > 0'}) do
yield
end
end
Notice how the build up of conditions is gone and instead replaced with *_scope calls. This has great implications for keeping with DRY principles.
For a fuller explanation check out these articles:
Setting up a fresh OSX rails install 5
While setting up a fresh rails install on a basically virgin system, I stumbled across this web site which goes over exactly that. So, instead of having to figure this all out for myself (again) I could simply follow the instructions of another.
All was not pain free however (why is the process never pain free?). When trying to start mysql via launchctl, mysqld would not start. In fact it didn’t seem to do anything! I could see the mysql.server start script being called but then it would just sit there.
Since that route failed me, I then tried the more direct route of starting via /opt/local/lib/mysql5/bin/mysqld. This seemed to start the server but it would then immediately stop. Checking the logs, I found this:
061224 23:09:52 mysqld started 061224 23:09:52 [Warning] Setting lower_case_table_names=2 because file system for /opt/local/var/db/mysql5/ is case insensitive 061224 23:09:52 InnoDB: Database was not shut down normally! InnoDB: Starting crash recovery. InnoDB: Reading tablespace information from the .ibd files... InnoDB: Restoring possible half-written data pages from the doublewrite InnoDB: buffer... 061224 23:09:52 InnoDB: Starting log scan based on checkpoint at InnoDB: log sequence number 0 36808. InnoDB: Doing recovery: scanned up to log sequence number 0 43655 061224 23:09:52 InnoDB: Starting an apply batch of log records to the database... InnoDB: Progress in percents: 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 InnoDB: Apply batch completed 061224 23:09:52 InnoDB: Started; log sequence number 0 43655 061224 23:09:52 [ERROR] /opt/local/libexec/mysqld: Can't find file: './mysql/host.frm' (errno: 13) 061224 23:09:52 [ERROR] /opt/local/libexec/mysqld: Can't find file: './mysql/host.frm' (errno: 13) 061224 23:09:52 [ERROR] Fatal error: Can't open and lock privilege tables: Can't find file: './mysql/host.frm' (errno: 13) 061224 23:09:52 mysqld ended
Looking up the mysql/host.frm complaint with google led me to this thread on linuxquestions. Bullet point #5 of “Butt-Ugly“‘s response solved my problem. Looks like perhaps darwinports or myself had created this database with the root user instead of the mysql user causing mysqld to have permissions problems when trying trying to read files it needed.
Removing the files in that directory followed by a restart of the server fixed the problem and I was on my way to mysql bliss.
Acts As Flaggable updated 4
Just checked in a small update to Acts As Flaggable that includes the following
- Incorporates suggestion from bitbutter to allow add_flag to take either a Flag object (as before) or a Hash. If passed a Hash it creates a Flag object from the hash you passed in.
- Added user_has_flagged? instance method to tell you if a user has flagged an object at all or flagged it with a specific flag
Grab it from trunk in the normal way!
OSX, SQLite3, and Rails 17
While preparing my travel laptop for rails work, I decided to give SQLite a try. I figured, “no problem”, rails was simple enough to setup for MySQL, certainly it would be just as easy for SQLite. I was almost right.
After setting up the database.yml file to use sqlite3 instead of mysql, I started seeing this problem:
SQLite3::SQLException: near “ADD”: syntax error: ALTER TABLE blah blah blah
After some googling, I found this post at another blog site. Basically it suggests ensuring you have the latest sqlite3 installed and the latest sqlite3-ruby gem. After some port magic and a quick gem update, I was totally up to date.
But I STILL had the same problem! Where did I go wrong? I reread Mark Cornick’s post and noticed this little note at the bottom
BTW, hopefully everyone knows this by now, but sqlite3-ruby won’t even link against your libsqlite3 unless SWIG is installed. Without SWIG, you get an incredibly strange sqlite3-ruby that stopped living and became a crazy mixed-up zombie
SWIG? I had never heard of SWIG before. Well, I found it here. SWIG basically generates code that connects various high level languages (such as Ruby) to C/C++ libraries. I’m assuming this is how ruby creates it’s bindings to sqlite3.
Once I had SWIG installed, I did a quick uninstall and reinstall of sqlite3-ruby and I was in business, migrations and all.
For more info on installing SQLite for use with rails, check out this how to wiki page off the main rails wiki.
Acts As Flaggable released 18
Here’s my first stab at a rails plugin, small as it may be.
Acts As Flaggable is a model modifier which allows flags to be associated with records. Authors of community driven sites may find this useful for quickly adding the ability to mark records as “spam” or “inappropriate”. There’s also facilities in place to automatically take a specific action automatically if a record has been flagged a certain way too many times (Think auto-removing posts that have been marked as “spam”).
To install:
script/plugin install http://svn.baconbear.com/rails_plugins/acts_as_flaggable/trunk
To prepare your database, create a migration with the following:
def self.up
create_table :flags, :force => true do |t|
t.column :flag, :string, :default => ""
t.column :comment, :string, :default => ""
t.column :created_at, :datetime, :null => false
t.column :flaggable_id, :integer, :default => 0, :null => false
t.column :flaggable_type, :string, :limit => 15,
:default => "", :null => false
t.column :user_id, :integer, :default => 0, :null => false
end
add_index :flags, ["user_id"], :name => "fk_flags_user"
end
def self.down
drop_table :flags
end
To prepare your model:
class Model < ActiveRecord::Base
acts_as_flaggable
protected
# Flagged method is called after every add_flag. This callback method
# is totally optional and does not have to be included in the model
def flagged(flag, flag_count)
# Add code here to take action when flag reaches a certain flag_count
end
end
To use:
p = Post.find(someid)
p.add_flag Flag.new(:flag => :spam, :comment => 'some comment')
If you notice I used add_flag instead of the typical << operator allowed by rails. Currently it’s a requirement that you use add_flag if you need the flagged callback to be called. I’ll probably fix this in a future checkin.
Avid plugin users will recognize a lot of the code and README from the Acts As Commentable plugin. Thanks to the clear and readable manner Acts As Commentable was written in, it was a fairly easy change to morph the commentable plugin into the flaggable plugin I have here. So, special thanks to Juixe for releasing a well written plugin!
Grand opening
Here you have it, the grand opening post of the Bacon Bear Blog (BBB). We’ll be using this space to talk about a variety of technology related topics as well as fun articles from around the web. We’ll try to keep it focused to these major areas:
- The various projects Bacon Bear Productions publishes (icalify, stockedornot, etc)
- Rails, web publishing, and development as a whole
- Fun articles, with a geeky bend
Hope to see you again! And so does the Bacon Bear (You’ll hear more from him in the near future).
