EphemeralModel, for Rails 2.2.2 form validation without a DB table

29 11 2008

I recently upgraded WhatYouAte.com to Rails 2.2.2. I had been using advice from the Rails Wiki’s HowToUseValidationsWithoutExtendingActiveRecord page. I was using a class based on the RailsWeenie code (that site is down now) and it stopped working. Here’s a new replacement hack that works almost identically.

# Usage: in the faux-model class, include EphemeralModel and ActiveRecord::Validations
# Then just say "column :foo" to set up a property called 'foo' for validation
module EphemeralModel
    # Stubbing methods from ActiveRecord::Base that ActiveRecord::Validations may call
    def EphemeralModel.included(mod)
        def mod.self_and_descendents_from_active_record; [self]; end
        def mod.human_attribute_name(arg); arg.to_s; end
        def mod.human_name; self.name; end
        def mod.column(attr_name)
            attr_name = attr_name.to_s
            column_names.push(attr_name) unless column_names.include?(attr_name)
            attr_accessor attr_name
        end
        mod.module_eval do
            def self.column_names
                cn = self.instance_variable_get(:@column_names)
                if cn.nil?
                    cn = self.instance_variable_set(:@column_names, [])
                end
                cn
            end
        end
    end
    def save; end
    def save!; end
    def update_attribute; end
    def new_record?; end

    def initialize(initial_attributes = nil)
        initial_attributes.each{|k,v| instance_variable_set("@#{k}".to_sym, v)} if initial_attributes
    end

    def attributes
        @attributes = {}
        self.class.column_names.each do |colname|
            @attributes[colname]= instance_variable_get("@#{colname}".to_sym)
        end
        @attributes
    end

    def attribute_names
        self.class.column_names
    end

    def [](name); attributes[name.to_s]; end

    def []=(name, value)
        instance_variable_set("@#{name}".to_sym, value)
        # print "set #{name} to " + instance_variable_get("@#{name}".to_sym) + ".\n" # DEBUG
    end
end

Actions

Informations

One response to “EphemeralModel, for Rails 2.2.2 form validation without a DB table”

29 11 2008
Pervasive Code » Things I had to fix for Rails 2.2.2 (19:57:16) :

[...] I was using a nice hack from Technoweenie, to allow me to validate forms using the familiar ActiveRecord model validations API even if those forms were not backed by a database table (sometimes the UI just doesn’t look anything like the data model, y’know?). It broke, and I was unable to find any solutions from anyone else, so I wrote my own: EphemeralModel, for Rails 2.2.2 form validation without a DB table. [...]

Leave a comment

You can use these tags : <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>