ActiveRecord::Base Without Table

This came up a bit ago ( rails model attributes without corresponding column in db ) but it looks like the Rails plugin mentioned is not maintained ( http://agilewebdevelopment.com/plugins/activerecord_base_without_table ). Is there no way to do this with ActiveRecord as is?

If not, is there any way to get ActiveRecord validation rules without using ActiveRecord?

ActiveRecord wants the table to exist, of course.


This is an approach I have used in the past:

In app/models/tableless.rb

class Tableless < ActiveRecord::Base
  def self.columns
    @columns ||= [];
  end

  def self.column(name, sql_type = nil, default = nil, null = true)
    columns << ActiveRecord::ConnectionAdapters::Column.new(name.to_s, default,
      sql_type.to_s, null)
  end

  # Override the save method to prevent exceptions.
  def save(validate = true)
    validate ? valid? : true
  end
end

In app/models/foo.rb

class Foo < Tableless
  column :bar, :string  
  validates_presence_of :bar
end

In script/console

Loading development environment (Rails 2.2.2)
>> foo = Foo.new
=> #<Foo bar: nil>
>> foo.valid?
=> false
>> foo.errors
=> #<ActiveRecord::Errors:0x235b270 @errors={"bar"=>["can't be blank"]}, @base=#<Foo bar: nil>>

Validations are simply a module within ActiveRecord. Have you tried mixing them into your non-ActiveRecord model?

class MyModel
  include ActiveRecord::Validations

  # ...
end

I figure the more answers the better since this is one of the first results in google when searching for "rails 3.1 models without tables"

I've implements the same thing without using ActiveRecord::Base while including the ActiveRecord::Validations

The main goal was to get everything working in formtastic, and below I've included a sample payment that will not get saved anywhere but still has the ability to be validated using the validations we all know and love.

class Payment
  include ActiveModel::Validations
  attr_accessor :cc_number, :payment_type, :exp_mm, :exp_yy, :card_security, :first_name, :last_name, :address_1, :address_2, :city, :state, :zip_code, :home_telephone, :email, :new_record

  validates_presence_of :cc_number, :payment_type, :exp_mm, :exp_yy, :card_security, :first_name, :last_name, :address_1, :address_2, :city, :state

  def initialize(options = {})
    if options.blank?
      new_record = true
    else
      new_record = false
    end
    options.each do |key, value|
      method_object = self.method((key + "=").to_sym)
      method_object.call(value)
    end
  end

  def new_record?
    return new_record
  end

  def to_key
  end

  def persisted?
    return false
  end
end

I hope this helps someone as I've spent a few hours trying to figure this out today.