Introducing activerecord-tablefree
ActiveRecord Without a Database?
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
- 2.2.x series higher than 2.2.2 (a Rails 5 requirement)
- 2.3.x series
- 2.4.x series
- 2.5.x series
Supported ActiveRecord versions are
- 5.0.x series
- 5.1.x series
- 5.2.x series
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| %>
Your name: <%= f.text_field :name %>
Your email: <%= f.text_field :email %>
Your message: <%= 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'
comments powered by Disqus