activerecord-model-spaces

<img src=“https://travis-ci.org/mccraigmccraig/activerecord-model-spaces.png?branch=master” alt=“Build Status” /> <img src=“https://codeclimate.com/badge.png” alt=“Code Climate”/>

Provides a means of contextually associating sets of ActiveRecord models with database tables through a table_name method implementation

This can be used to maintain multiple independent versions of model datasets, for applications including multi-tenancy

Additionally, each model participating in a ModelSpace can optionally be assigned a number of “history versions”, and methods are provided to create new or updated versions of the datasets in a ModelSpace without causing locks or large transactions

Models which participate in a ModelSpace need only make sure that they use the table_name method whenever they refer to the database table. Since all ActiveRecord methods already do this, it is only application methods which generate SQL which must take care

Installation

gem "activerecord-model-spaces", "~> 0.1.0"

Usage

Include the ActiveRecord::ModelSpaces module in a model Class, and declare the model to be part of a ModelSpace, optionally specifying a number of history versions (which defaults to 0) and a base table name (from which contextual table names are constructed, and which defaults to the normal table name)

require 'active_record/model_spaces'

class AModel < ActiveRecord::Base
  include ActiveRecord::ModelSpaces

  in_model_space :metadata, :history_versions=>1, :base_table_name=>"unusual_models"
end

Each ModelSpace may have many models associated with it, but each model may only be associated with a single ModelSpace

At this point, the model can be used in ModelSpaces context, and data will be sourced from a different table according to the context, the context key and any history version. Outside of a ModelSpaces context the model will source data from it’s usual table

To establish a context use the with_context method, which provides a key to be used along with the ModelSpace name to generate the name of the database table to be used by the model for the duration of the context

AModel.table_name # "unusual_models"

ActiveRecord::ModelSpaces.with_context(:metadata, :one) do
  AModel.table_name # "metadata__one__unusual_models"
end

If the table to be used by a model within a context does not exist it will be created when the context is created. The created table will have the same schema as the normal model table

If a model is declared as having history_versions then historical copies of the tables will be maintained. New or updated versions of a model can be created using the new_version and updated_version class methods on the model Class, while a context for the ModelSpace is established. The new versions are only visible within the context that they are created in, until the context complete without Error, at which point any new context established for that ModelSpace will use the newly created versions. Table names wrap once the given number of history version tables have been used

class BModel < ActiveRecord::Base
  include ActiveRecord::ModelSpaces

  in_model_space :metadata, :history_versions=>1
end

ActiveRecord::ModelSpaces.with_context(:metadata, :one) do
  AModel.table_name # "metadata__one__unusual_models"

  AModel.new_version do
    AModel.table_name # "metadata__one__unusual_models__1"
  end

  AModel.table_name # "metadata__one__unusual_models__1"

  BModel.table_name # "metadata__one__b_models"

  BModel.updated_version do
    BModel.table_name # "metadata__one__b_models__1"
  end

  BModel.table_name # "metadata__one__b_models__1"
end

ActiveRecord::ModelSpaces.with_context(:metadata, :one) do
  AModel.table_name # "metadata__one__unusual_models__1"
  BModel.table_name # "metadata__one__b_models__1"

  AModel.new_version do
      AModel.table_name # "metadata__one__unusual_models"
  end

  AModel.table_name # "metadata__one__unusual_models"
end

ActiveRecord::ModelSpaces.with_context(:metadata, :one) do
  AModel.table_name # "metadata__one__unusual_models"
end

Contributing to activerecord-model-spaces

  • Check out the latest master to make sure the feature hasn’t been implemented or the bug hasn’t been fixed yet.

  • Check out the issue tracker to make sure someone already hasn’t requested it and/or contributed it.

  • Fork the project.

  • Start a feature/bugfix branch.

  • Commit and push until you are happy with your contribution.

  • Make sure to add tests for it. This is important so I don’t break it in a future version unintentionally.

  • Please try not to mess with the Rakefile, version, or history. If you want to have your own version, or is otherwise necessary, that is fine, but please isolate to its own commit so I can cherry-pick around it.

Copyright © 2013 mccraig mccraig of the clan mccraig. See LICENSE.txt for further details.