Notes posted by LacKac
RSS feed
Setting ttl
Use the expires_in option to set a TTL for the cached item.
Rails.cache.write("top_items", :expires_in => 5.minutes)
You can use this with the fetch method as well:
Rails.cache.fetch("top_items", :expires_in => 5.minutes) do # some very expensive calculations end
Note: this only works with supporting cache stores, like the MemCacheStore

Creating additional cache stores
This method can be used to create additional cache stores for your application:
# creates a new Memory Store mem_store = ActiveSupport::Cache.lookup_store # creates a new MemCache Store mem_cache_store = ActiveSupport::Cache.lookup_store :mem_cache_store, 'localhost:11212', :namespace => 'other_stuff'
The method takes the same arguments as the cache_store config. For more information about that go to ActionController::Caching.

Re: Convert an Array of Arrays to a Hash using inject
If you’re sure you have a two-level array (no other arrays inside the pairs) and exactly two items in each pair, then it’s faster and shorter to use this:
array = [['A', 'a'], ['B', 'b'], ['C', 'c']] hash = Hash[*array.flatten]
For more than two-level deep arrays this will give the wrong result or even an error (for some inputs).
array = [['A', 'a'], ['B', 'b'], ['C', ['a', 'b', 'c']]] hash = Hash[*array.flatten] # => {"A"=>"a", "B"=>"b", "C"=>"a", "b"=>"c"}
But if you’re running Ruby 1.8.7 or greater you can pass an argument to Array#flatten and have it flatten only one level deep:
# on Ruby 1.8.7+ hash = Hash[*array.flatten(1)] # => {"A"=>"a", "B"=>"b", "C"=>["a", "b", "c"]}

Re: Helper method taking a block
The same using the ActionView::Helpers::TagHelper#content_tag and ActionView::Helpers::CaptureHelper#capture methods:
def render_tree(collection, &block) concat( content_tag(:ul, collection.collect { |item| content_tag(:li, capture(item, &block)) }.join("\n") ), block.binding ) end
The benefit is that it’s easier to improve with html attributes (just add a hash of options to the content_tag call) and it makes just one call to concat (which probably makes it faster).

How to handle the MultiparameterAssignmentErrors exception
If you expect to get this error, do this in your controller:
def create @event = Event.new @event.attributes = params[:event] @event.save! rescue ActiveRecord::MultiparameterAssignmentErrors => e e.errors.each do |error| @event.errors.add(error.attribute, ActiveRecord::Errors.default_error_messages[:invalid]) end rescue ActiveRecord::RecordInvalid # event is invalid ensure if @event.errors.empty? and not @event.new_record? redirect_to event_path(@event) else render :action => :new end end
If attribute assignment gives the MultiparameterAssignmentErrors exception we handle it by adding ‘invalid’ errors to the attributes involved. We also rescue the RecordInvalid exception and handle all the redirecting/rendering in the ensure block.

If you need something more
Use the brilliant chronic gem: http://chronic.rubyforge.org/
require 'chronic' Time.now # => Fri Jul 25 00:00:25 0200 2008 Chronic.parse 'tomorrow 8 in the evening' # => Sat Jul 26 20:00:00 0200 2008 Chronic.parse 'next Monday noon' # => Mon Jul 28 12:00:00 0200 2008 Chronic.parse 'first Wednesday of Aug' # => Wed Aug 06 12:00:00 0200 2008 Chronic.parse 'first Wednesday of Aug 7pm' # => Wed Aug 06 19:00:00 0200 2008