appraisal-rb Logo by Aboling0, CC BY-SA 4.0 kettle-rb Logo by Aboling0, CC BY-SA 4.0 floss-funding Logo by Aboling0, CC BY-SA 4.0 galtzo-floss Logo by Aboling0, CC BY-SA 4.0 omniauth Logo by (presumed) tomeara, (presumed) MIT resque Logo by Resque development team, MIT rubocop-lts Logo by Aboling0, CC BY-SA 4.0 oauth Logo by Chris Messina, CC BY-SA 3.0 ruby-openid Logo by Aboling0, CC BY-SA 4.0

Introducing activerecord-tablefree

ActiveRecord Without a Database?

Total Downloads Downloads Today Build Test Coverage Maintainability Network Stars Version Open Source Helpers Depfu Chat License: MIT

ActiveRecord Tablefree Models provides a simple mixin for creating models that are not bound to the database. This approach is useful for taking advantage of the features of ActiveRecord such as validation, relationships, nested_attributes, etc.

This can also be very useful in testing where a mock-like object will suffice.

This gem is exceptionally hacky. For an alternative solution, primarily aimed at testing, that is less hacky, see my other gem anonymous_active_record!

Why, why, why

Why would you ever consider this gem as opposed to ActiveModel?

ActiveModel::Model does not support relations and nested attributes.

Installation

ActiveRecord Tablefree is distributed as a gem, which is how it should be used in your app.

Include the gem in your Gemfile:

gem "activerecord-tablefree", "~> 3.0"

Supported Versions

Supported ruby version are

Supported ActiveRecord versions are

If you are using an older ActiveRecord version you can use the gem activerecord-tableless

This gem tries to maintain the same API as the older activerecord-tableless gem.

Usage

Define a model like this:

class ContactMessage < ActiveRecord::Base
  has_no_table
  column :name, :string
  column :email, :string
  column :message, :string
  validates_presence_of :name, :email, :message
end

You can now use the model in a view like this:

form_for :contact_message, @contact_message do |f|
  f.text_field :name
  f.text_field :email
  f.text_field :message
end

And in the controller:

def contact_message
  @contact_message = ContactMessage.new
  if request.post?
    @contact_message.attributes = params[:contact_message]
    if @contact_message.valid?
      # Process the message...
    end
  end
end

If you wish (this is not recommended), you can pretend you have a succeeding database by using

has_no_table :database => :pretend_success

Associations

Some model as before, but with an association to a real DB-backed model.

class ContactMessage < ActiveRecord::Base
  has_no_table
  column :message, :string
  column :email, :string
  validates_presence_of :name, :email
  belongs_to :contact, foreign_key: :email, primary_key: :email
end

class Contact < ActiveRecord::Base
  validates_presence_of :name, :email
  has_one :contact_message, foreign_key: :email, primary_key: :email, dependent: nil
end

Obviously the association is not full-fledged, as some traversals just won’t make sense with one side not being loadable from the database. From the ContactMessage you can get to the Contact, but not vice versa.

contact = Contact.new(name: 'Boo', email: 'boo@example.com')
contact_message = ContactMessage.new(contact: contact)
contact_message.email
# => 'boo@example.com'