Further Enumerable::Proxy
My last post about Enumerable::Proxy ended with the possibility of being able to call .map.to_s, which appealed to me. I finally got around to making that possible.
Enumerable::Proxy
I’ve been playing with a pattern that replaces the Rails Symbol#to_proc pattern. Instead of doing
@my_objects.each(&:save!)
You would do
@my_objects.proxy(:each).save!
Instead of Rails :unique finder, Array#singular
There was recently some talk about a suggested :unique finder for rails.
Although this seems like overkill, I occasionally do things like array.size == 1 && array.first, which is basically all the :unique finder would do.
Without further ado, here’s a five-line monkeypatch to Array that lets you get the singular item from an array (or blow up if you expect one and there isn’t):
class Array def singular?() size == 1 end def singular() singular?? first : nil end def singular!() singular or raise "not singular" end end
Now you can simulate the :unique finder just by doing
my_singular_wibble = Widget.wibbles.first.singular.
This, along with lots of other fun monkeypatches, is now in freighthopper, my collection of extensions and monkeypatches.
View CommentsPromiscuous models and capable controllers
By default ActiveRecord allows visitors access to any writer method, that is, any method ending with an equal sign. This comes courtesy of the ActiveRecord::Base#attributes= method, which is used internally by the main methods that handle creating and updating records, including new(), create(), and update_attributes().
This topic recently came up on the SF and East Bay Ruby meetup lists (original message here, associated blog post here). I started writing a response in my email client and decided it was big enough that it would benefit from a blog post.
Abstract: Even though attr_protected and attr_accessible exist, models
shouldn’t be filtering — controllers should be. Filtered params should be defined on the model for locality of reference, not on the controller. Hash#slice and Hash#except aren’t enough because they don’t handle nested hashes, so I explore a recursive filter (blacklist & whitelist).
Ruby local variables in scope
Some neat Ruby esoterica I ran into recently:
a, b = 1, 2 local_variables #=> ["_", "a", "b"] local_variables.inject({}){|h,v|h.merge v.to_sym => eval(v)} #=> {:b=>2, :a=>1, :_=>["_", "a", "b"]}
Now, I’m not quite sure what that’s good for, but it’s neat to know about.
View Comments