ActiveItem
ActiveRecord-like ORM for AWS DynamoDB.
Installation
gem 'activeitem'
Configuration
ActiveItem.configure do |config|
config.table_prefix = 'myapp'
config.environment = 'production'
config.logger = Rails.logger # or any Logger-compatible object
end
Table names are generated as {prefix}-{environment}-{model-name-pluralized}.
Usage
class User < ActiveItem::Base
self.primary_key = :user_id
attr_accessor :email, :name, :status
indexes(
'EmailIndex' => { partition_key: 'email' },
'StatusIndex' => { partition_key: 'status', sort_key: 'createdAt' }
)
validates :email, presence: true
validates :email, uniqueness: true
scope :active, -> { where(status: 'active') }
before_create :set_defaults
private
def set_defaults
self.status ||= 'active'
end
end
CRUD
user = User.create!(email: 'alice@example.com', name: 'Alice')
user = User.find('user-123')
user.update(name: 'Alice Smith')
user.destroy
Querying
User.where(status: 'active', index: 'StatusIndex')
User.where(email: 'alice@example.com', index: 'EmailIndex').first
User.where.not(status: 'deleted')
User.all.limit(50)
User.count
User.exists?('user-123')
Associations
class Post < ActiveItem::Base
belongs_to :user
has_many :comments, foreign_key: 'post_id', index: 'PostIndex'
end
Transactions
ActiveItem::Base.transaction do |txn|
txn.put(new_record)
txn.update(existing_record)
txn.delete(old_record)
end
Pagination
result = Post.where(user_id: id, index: 'UserIndex').page(cursor, per_page: 25)
result.items # => [Post, Post, ...]
result. # => { next_cursor: "...", has_more: true, per_page: 25 }
Composed Of (Value Objects)
class Customer < ActiveItem::Base
attr_accessor :street, :city, :state, :zip_code
composed_of :address, class_name: 'Address', mapping: {
street: :street, city: :city, state: :state, zip_code: :zip_code
}
end
License
MIT