README.md in pg_serializable-0.1.1 vs README.md in pg_serializable-1.0.0

- old
+ new

@@ -2,10 +2,62 @@ This is experimental. Serialize json directly from postgres (9.4+). +## Why? +Models: +```ruby +class Product < ApplicationRecord + has_many :categories_products + has_many :categories, through: :categories_products + has_many :variations + belongs_to :label +end +class Variation < ApplicationRecord + belongs_to :product + belongs_to :color +end +class Color < ApplicationRecord + has_many :variations +end +class Label < ApplicationRecord + has_many :products +end +class Category < ApplicationRecord + has_many :categories_products + has_many :products, through: :categories_products +end +``` + +Using Jbuilder+ActiveRecord: +```ruby +class Api::ProductsController < ApplicationController + def index + @products = Product.limit(200) + .order(updated_at: :desc) + .includes(:categories, :label, variations: :color) + render 'api/products/index.json.jbuilder' + end +end +``` +```shell +Completed 200 OK in 2521ms (Views: 2431.8ms | ActiveRecord: 45.7ms) +``` + +Using PgSerializable: +```ruby +class Api::ProductsController < ApplicationController + def index + render json: Product.limit(200).order(updated_at: :desc).json + end +end +``` +```shell +Completed 200 OK in 89ms (Views: 0.1ms | ActiveRecord: 78.9ms) +``` + ## Installation Add this line to your application's Gemfile: ```ruby @@ -28,12 +80,14 @@ class Product < ApplicationRecord include PgSerializable serializable do - attributes :name, :id - attribute :name, label: :test_name + default do + attributes :name, :id + attribute :name, label: :test_name + end end end ``` You can also include it in your `ApplicationRecord` so all models will be serializable. @@ -85,40 +139,87 @@ ``` Wrap attributes in custom sql ```ruby serializable do - attributes :id - attribute :active, label: :deleted { |v| "NOT #{v}" } + default do + attributes :id + attribute :active, label: :deleted { |v| "NOT #{v}" } + end end ``` +```sql +SELECT + COALESCE(json_agg( + json_build_object('id', a0.id, 'deleted', NOT a0.active) + ), '[]'::json) +FROM ( + SELECT "products".* + FROM "products" + ORDER BY "products"."updated_at" DESC + LIMIT 2 +) a0 +``` ```json [ { "id": 503, - "deleted": true + "deleted": false }, { "id": 502, - "deleted": true + "deleted": false } ] ``` +### Traits +```ruby +serializable do + default do + attributes :id, :name + end + trait :simple do + attributes :id + end +end +``` + +```ruby +render json: Product.limit(10).json(trait: :simple) +``` + +```json +[ + { "id": 1 }, + { "id": 2 }, + { "id": 3 }, + { "id": 4 }, + { "id": 5 }, + { "id": 6 }, + { "id": 7 }, + { "id": 8 }, + { "id": 9 }, + { "id": 10 } +] +``` + ### Associations Supported associations: - `belongs_to` - `has_many` - `has_many :through` - `has_one` #### belongs_to ```ruby serializable do - attributes :id, :name - belongs_to: :label + default do + attributes :id, :name + belongs_to: :label + end end ``` ```json [ { @@ -141,25 +242,31 @@ #### has_many Works for nested relationships ```ruby class Product < ApplicationRecord serializable do - attributes :id, :name - has_many: :variations + default do + attributes :id, :name + has_many: :variations + end end end class Variation < ApplicationRecord serializable do - attributes :id, :hex - belongs_to: :color + default do + attributes :id, :name + belongs_to: :color + end end end class Color < ApplicationRecord serializable do - attributes :id, :hex + default do + attributes :id, :hex + end end end ``` ```json [ @@ -213,18 +320,22 @@ class Product < ApplicationRecord has_many :categories_products has_many :categories, through: :categories_products serializable do - attributes :id - has_many :categories + default do + attributes :id + has_many :categories + end end end class Category < ApplicationRecord serializable do - attributes :name, :id + default do + attributes :name, :id + end end end ``` ```json @@ -257,9 +368,109 @@ } ] ``` #### has_one TODO: write examples + +### Association Traits +Models: +```ruby +class Product < ApplicationRecord + has_many :variations + + serializable do + default do + attributes :id, :name + end + + trait :with_variations do + attributes :id + has_many :variations, trait: :for_products + end + end +end + +class Variation < ApplicationRecord + serializable do + default do + attributes :id + belongs_to: :color + end + + trait :for_products do + attributes :id + end + end +end +``` + +Controller: +```ruby +render json: Product.limit(3).json(trait: :with_variations) +``` + +```json +[ + { + "id":1, + "variations":[ + + ] + }, + { + "id":2, + "variations":[ + { + "id":5 + }, + { + "id":4 + }, + { + "id":3 + }, + { + "id":2 + }, + { + "id":1 + } + ] + }, + { + "id":3, + "variations":[ + { + "id":14 + }, + { + "id":13 + }, + { + "id":12 + }, + { + "id":11 + }, + { + "id":10 + }, + { + "id":9 + }, + { + "id":8 + }, + { + "id":7 + }, + { + "id":6 + } + ] + } +] +``` ## Development TODO