Posts Tagged ‘playground’

rajax.js

// RAjax Namespace
var RAjax = {};

// Basic Logger facility that supports logging to
// an HTMLElement, the Firebug console and alerts.
// If provided with a valid DOM id, it will append
// log messages to this element. If it can't find
// the DOM id you provided, it will try to use
// the Firebug console instead (you can make sure
// that this will be found by installing Firebug Lite
// from http://www.getfirebug.com/lite.html website).
// Finally, if it can't find a console Object to log to,
// and you tell it so by passing true as the
// second parameter to initialize, it will fall back
// to those nasty alerts, that can lead to very unfortunate
// situations dependending on which situations (events)
// you use them!

RAjax.Logger = Class.create({

  initialize: function(stream, performAlerts) {
    this.stream = (s = $(stream)) ? s : console; // maybe null
    this.performAlerts = performAlerts || false;
  },

  log: function(message) {
    if(PERFORM_LOGGING) {
      if(this.stream) {
        // Firebug console or HTMLElement present
        if(this.logsToFirebug()) {
          // Logging to Firebug console
          this.stream.log(message);
        } else {
          // Logging to HTMLElement
          this.stream.insert({bottom: this.formattedMessage(message)});
        }
      } else { // no stream present
        // fallback to annoying alerts
        alert(this.formattedMessage(message));
      }
    }
  },

  clear: function() {
    if(this.logsToPage()) {
      this.stream.update('');
    }
  },

  // override this if you need different formatting
  formattedMessage: function(message) {
    return "
  • ” + message + “
  • “; }, debug: function(message) { this.log(message); }, error: function(message) { this.log(”ERROR: ” + message); }, // utility methods logsToFirebug: function() { return !!this.stream.log; }, logsToPage: function() { return this.stream && !this.firebugPresent(); } }); // additional supported callbacks RAjax.EXTENDED_CALLBACKS = [ “onPOSTSuccess” , “onPOSTFailure”, “onGETSuccess” , “onGETFailure”, “onPUTSuccess” , “onPUTFailure”, “onDELETESuccess”, “onDELETEFailure” ];

    Read more »

    validatable_hash

      # -----------------------------------------------------------------------
      # Don't like nasty conditionals when doing option checking ?
      # Good news! They have already been done for u ... by snusnu
      # -----------------------------------------------------------------------
      #
      # How does it work?
      #
      # 1) instance method acts_as_option_hash! gets defined on Hash
      # 2) You call acts_as_option_hash! on any old Hash instance
      # 3) acts_as_option_hash! yields an instance of OptionSpec
      # 4) This instance IS ONLY ADDED TO YOUR Hash INSTANCE
      #    (not to class Hash itself => it becomes a singleton method)
      # 5) You spec your options using methods on OptionSpec
      #    (you will be for
      # 6) Once acts_as_option_hash! returns it evaluates the passed options
      # 7) a) Everything is fine you go use your options
      #       without any further checks
      # 7) b) An InvalidOptions exception is thrown because the passed options
      #       don't match your spec.
      #
      # ----------------------------------------------------------------------
      #
      # DESIRED USAGE
      #
      # ----------------------------------------------------------------------
      #
      # class Foo
      #
      #   options_for :foo do |spec|
      #     spec.only_one_of do |group|
      #       group.option :only do |o|
      #         o.allow [ :sleep, 1, String, Float ]
      #         o.reject [ :bar, 2, 3.14 ]
      #       end
      #       group.option :only do |o|
      #         o.allow [ :sleep, 1, String, Float ]
      #         o.reject [ :bar, 2, 3.14 ]
      #       end
      #     end
      #
      #     spec.option :only do |o|
      #       o.allow [ :sleep, 1, String, Float ], :unless => :except
      #       o.reject [ :bar, 2, 3.14 ]
      #
      #     spec.option :foo do |o|
      #       if spec.present [ :bam ] do ||
      #         o.allow => [ :sleep, 1, String, Float ]
      #         o.reject => [ :bar, 2, 3.14 ]
      #       end
      #       o.if_present [ :bam ]
      #       o.unless_present [ [ "test", :spec ], "fun" ]
      #     end
      #   end
      #
      #   OPTION_SPEC = lambda do |spec|
      #     spec.option :foo do |o|
      #       if spec.present [ :bam ] do ||
      #         o.allow => [ :sleep, 1, String, Float ]
      #         o.reject => [ :bar, 2, 3.14 ]
      #       end
      #       o.if_present [ :bam ]
      #       o.unless_present [ [ "test", :spec ], "fun" ]
      #     end
      #   end
      #
      # end

    Read more »

    (pretty?) declarative exception handling with ruby

    # Allows you to define your exception handling like this:
    # -------------------------------------------------------
    #
    # class InvalidFooException < Exception
    # end
    #
    # class Foo
    #   include DeclarativeExceptions
    #   register_exception :invalid_foo do |exception|
    #     exception.type = InvalidFooException
    #     exception.message = <<-MSG
    #       Parameter #? is invalid for foo
    #     MSG
    #   end
    #
    #   def foo(value)
    #     raise_exception :invalid_foo, value
    #   end
    # end
    
    module DeclarativeExceptions
    
      class InvalidVariableBindings < Exception
      end
    
      class ExceptionSpec
        attr_accessor :type, :message
      end
    
      module ObjectClassMethods
    
        def register_exception(key)
          yield @spec = ExceptionSpec.new
          (@exceptions ||= {})[key] = @spec
        end
    
        def exceptions
          @exceptions ? @exceptions.dup : nil
        end
    
      end
    
      module ObjectInstanceMethods
    
        protected
    
        def raise_exception(key, *values)
          exception = self.class.exceptions[key]
          raise exception.type, exception.message.replace_variables(*values)
        end
    
      end
    
      module StringInstanceMethods
    
        def replace_variables(*values)
          expected_size, provided_size = scan('#?').size, values.size
          raise_if_bind_arity_mismatch!(expected_size, provided_size)
          bound = values.dup
          gsub('#?') { quote_bound_value(bound.shift) }
        end
    
        private
    
        # support only simple quoting
        # quote_start and quote_end are always the same
        def quote_bound_value(v, quote_char = '\'')
          "#{quote_char}#{v}#{quote_char}"
        end
    
        def raise_if_bind_arity_mismatch!(expected_size, provided_size)
          unless expected_size == provided_size
            msg = <<-EOS
              You provided a wrong number of bind variables:
              (#{provided} for #{expected}) in: #{self}"
            EOS
            raise InvalidVariableBindings, msg
          end
        end
    
      end
    
    end

    singleton methods (for options checking maybe?)

    # Did this out of interest, only to find out that
    # the same functionality already exists in ruby ;-)
    # Obviously, I'm redefining extend on Object,
    # but it still does the expected thing.
    
    class Object
      def extend(m)
        instance_eval do
          (class << self; self; end).send :include, m
        end
      end
    end

    irb toplevel methods are added to Object

    irb(main):001:0> def foo
    irb(main):002:1>   puts "foo"
    irb(main):003:1> end
    => nil
    irb(main):004:0> foo
    foo
    => nil
    irb(main):005:0> o = Object.new
    => #
    irb(main):006:0> o.foo
    foo
    => nil

    overriding with alias

    >> class Foo
    >>   def foo
    >>     puts "foo"
    >>   end
    >> end
    => nil
    >> class Bar < Foo
    >>   def bar
    >>     puts "bar"
    >>   end
    >>   alias :foo :bar
    >> end
    => nil
    >> b = Bar.new
    => #
    >> b.foo
    bar
    => nil

    Kernel methods (for options checking maybe?)

    # Notice the subtle but important difference?
    
    # RIGHT way
    # --------------------------
    >> module Kernel
    >>   def satisfies?
    >>     yield(self) == true
    >>   end
    >>   def is_one_of?(*args)
    >>     predicates = args.inject([]) { |m, a| m << "v.is_a?(#{a})" }.join('||')
    >>     satisfies?(&(eval "lambda { |v| (#{predicates})}"))
    >>   end
    >>   def is_not_one_of?(*args)
    >>     !is_one_of?(*args)
    >>   end
    >> end
    => nil
    >> nil.is_a? NilClass
    => true
    >> nil.is_one_of? NilClass
    => true
    >> nil.is_not_one_of? NilClass
    => false
    >> nil.is_one_of? String, Symbol
    => false
    >> nil.is_not_one_of? String, Symbol
    => true
    >>
    ?> 3.is_one_of? Integer, String
    => true
    >> :foo.is_one_of? String, Symbol
    => true
    >> {}.is_one_of? String, Hash
    => true
    
    # WRONG way
    # ---------------------------
    >> module Kernel
    >>   def satisfies
    >>     yield self == true
    >>   end
    >> end
    => nil
    >> o = Object.new
    => #
    >> o.satisfies { |v| !v.nil? }
    => true
    >> nil.satisfies { |v| !v.nil? }
    => true
    >> l = lambda { |v| !v.nil? }
    => #
     >> o.satisfies(&l)
    => true

    DRYing associations and behavior

    module CommonBehaviour
      def self.included(base)
        base.class_eval <<-EOC
          belongs_to :foo
          has_many :bars
          delegate :baz, :to => :survey_execution
        EOC
        base.send :include, InstanceMethods
      end
    
      module InstanceMethods
        def bla
          p 'bla'
        end
      end
    end
    
    class OneOfCommon < ActiveRecord::Base
      include CommonBehaviour
    end

    blog archive helper

    # ------------------------------------------
    #                 routes.rb
    # ------------------------------------------
    
    # show posts by date
    map.connect ':year/:month/:day',
      :controller => 'posts',
      :action => 'index',
      :year => /\d{4}/,
      :month => /\d{1,2}/,
      :day => /\d{1,2}/
    
    # show posts by month
    map.connect ':year/:month',
      :controller => 'posts',
      :action => 'index',
      :year => /\d{4}/,
      :month => /\d{1,2}/
    
    # ------------------------------------------
    #            post_controller.rb
    # ------------------------------------------
    
    def index
      if params[:year] && params[:month]
        datestring = "#{params[:year]}-#{params[:month]}"
        datestring << "-#{params[:day]}" if params[:day]
          @posts = Post.find_all_by_date_like(datestring)
        else
          @posts = Post.find(:all)
        end
    
        respond_to do |format|
          format.html # index.html.erb
          format.xml  { render :xml => @posts }
          format.atom
        end
      end
    end
    
    # ------------------------------------------
    #          post.rb
    # ------------------------------------------
    
    class Post < ActiveRecord::Base
      class << self
        def find_all_by_date_like(datestring)
          self.find(:all, :conditions => ['created_at LIKE ?', datestring + '%'])
        end
      end
      #...
    end
    
    # ------------------------------------------
    #          application_helper.rb
    # ------------------------------------------
    
    MONTHS =
      [
        'January', 'February', 'March', 'April', 'May', 'June',
        'July', 'August', 'September', 'October', 'Novemeber', 'December'
      ]
    
    def archive_content(posts)
      raise ArgumentError unless block_given?
      with_unique_dates_from_resource posts do |year, month|
        link_name = "#{MONTHS[month.to_i - 1]} #{year}"
        yield(link_to(link_name, "/#{year}/#{month}"))
      end
    end
    
    def with_unique_dates_from_resource(resource, timestamp = :created_at, find_options = {})
      if resource.is_a?(Array)
        collection = resource
      else
        proxy = resource.to_s.singularize.camelcase.constantize
        collection = proxy.find(:all, find_options)
      end
      collection.map do |model|
        model.send(timestamp).strftime("%Y/%m")
      end.uniq.each do |date|
        dates = date.split('/')
        yield(*dates)
      end
    end
    
    # ------------------------------------------
    #               in some view
    # ------------------------------------------
    
    <% archive_content :posts do |archive_link| %>
    
  • <%= archive_link %>
  • <% end %> # or <% archive_content Post.find(:all) do |archive_link| %>
  • <%= archive_link %>
  • <% end %>

    rails data migrations, part 2

    
    class DataMigration < ActiveRecord::Migration
    
      class << self
    
        def fixtures(file_name, options = { :folder => 'data' })
          @file_name, @folder_name = file_name, options[:folder]
        end
    
        def migrate(direction)
          super(direction) # perform migration
          if direction == :up && valid_options_present?
            require 'active_record/fixtures'
            data_migration_path = "#{RAILS_ROOT}/db/migrate/#{@folder_name}"
            Fixtures.create_fixtures(data_migration_path, @file_name.to_s)
            say "DataMigration INFO"
            say "Loaded #{data_migration_path}/#{@file_name.to_s}.yml", true
          end
        rescue Errno::ENOENT => e
          say "Snusnu::DataMigration WARNING"
          say e.message, true
        end
    
        private
    
        def valid_options_present?
          [ @file_name, @folder_name ].all? do |v|
            v && (v.is_a?(String) || v.is_a?(Symbol))
          end
        end
    
      end
    
    end
    
    class CreateMyMigration < DataMigration
      fixtures :people #, :folder => "fixtures"
      def self.up
        create_table :people, :force => true do |t|
          #...
        end
      end
    end

    « Older Entries