Project

seria

0.0
No commit activity in last 3 years
No release in over 3 years
Add dynamic JSON data to active records. Access it like documents. Query it.
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
 Dependencies

Development

~> 1.3
>= 0
>= 0

Runtime

> 3.0
 Project Readme

Seria

Gem Version

Why Seria?

I wrote this gem because I needed to be able to load my ARs with key-value attributes without running migrations, in a similar way to dynamic_attributes gem. But I also needed to be able to query the data, so storing it in a JSON wasn't a good enough solution. There were still mongodb documents, but I wanted to be able to run join queries, and exporting data to another database was an overkill.

Seria lets you add completely dynamic data to your ARs. Seria doesn't store your hash data in a JSON, but in separate records making it queryable. Seria will automatically cast your attributes back to their original type when loaded from the database - no more messy string manipulations.

Installation

Add this line to your application's Gemfile:

gem 'seria'

And then execute:

$ bundle

Or install it yourself as:

$ gem install seria

Usage

Generate the info table

$ rails g info_table book
$ rake db:migrate

Register your info table owner and start loading attributes

class Book < ActiveRecord::Base
  include Seria::InfoTableOwner
end

book = Book.new(title: "The portable")
book.infos["price"]=100.0
book.infos["author"] = 'Dorothy Paker'
book.infos["recommended"] = true
book.save

book = Book.last
book.infos["price"]
# => 100.0
book.infos["recommended"]
# => true

Or, avoid awkward association syntax and call directly

Seria.configure do |config|
  config.perform_lookup_on_method_missing = true
end

book.recommended = false
book.recommended
# => false

Querying

Seria stores your data in separate table with the fields foreign_id, field_name, field_value and field_type

/* The values are saved as strings, so when querying the database you need to convert to your original type: */
select CAST(field_value as decimal(10,2)) as price from book_infos where field_name = "price"
class BookInfo #yes, you can define yourself
  scope :prices, proc{ where('field_name="price"') }
end

cheep_books = BookInfo.prices.where('CAST(field_value as decimal(10,2)) < 10') #database
cheep_books = BookInfo.prices.select{|p| p.field_value < 10} #memory

Configure your own table-names, fields and converters

Seria.configure do |config|
  config.fields.key = :fkey
  config.fields.value = :fvalue
  config.fields.type = :ftype
  config.descriptor = :data
  config.converters["price"] = Seria::BigDecimalConverter
end

Contributing

  1. Fork it
  2. Create your feature branch (git checkout -b my-new-feature)
  3. Commit your changes (git commit -am 'Add some feature')
  4. Push to the branch (git push origin my-new-feature)
  5. Create new Pull Request