diff --git a/README.md b/README.md index 51d66ed..cb52e69 100644 --- a/README.md +++ b/README.md @@ -1,128 +1,136 @@ -# ArSync - Reactive Programming with Ruby on Rails +# ArSync — Reactive data sync for Ruby on Rails -Frontend JSON data will be synchronized with ActiveRecord. +Keep frontend JSON in sync with ActiveRecord, automatically. -- Provides an json api with query(shape of the json) -- Send a notificaiton with ActionCable and automaticaly updates the data +- A read API where the client requests the shape of the JSON (built on [ar_serializer](https://github.com/tompng/ar_serializer)). +- When a record changes, a notification is pushed (over ActionCable) and the data on the client updates in place. +- Generates TypeScript types so query results are fully typed. ## Installation -1. Add this line to your application's Gemfile: +Add the gem: + ```ruby gem 'ar_sync' ``` -2. Run generator +Run the generator (creates `SyncSchema`, the API controller, an ActionCable channel, an initializer, and routes): + ```shell rails g ar_sync:install ``` -## Usage +## Defining sync models + +Declare which fields and associations are synced, and how change notifications +propagate to parents. -1. Define parent, data, has_one, has_many to your models ```ruby class User < ApplicationRecord has_many :posts - ... sync_has_data :id, :name sync_has_many :posts end class Post < ApplicationRecord belongs_to :user - ... sync_parent :user, inverse_of: :posts sync_has_data :id, :title, :body, :createdAt, :updatedAt sync_has_one :user, only: [:id, :name] end ``` -2. Define apis +DSL: + +- `sync_has_data` / `sync_has_one` / `sync_has_many` — fields and associations to sync. +- `sync_parent parent, inverse_of:` — when this record changes, notify `parent` through its `inverse_of` field. Options: + - `only_to:` — notify only a specific user (Symbol/Proc). + - `watch:` — fire only when the given column (or Proc value) actually changes. + +Field options (`type:`, `includes:`, `preload:`, `only:`, `except:`, `count_of:`, `permission:`, …) are passed through to ar_serializer — see its [README](https://github.com/tompng/ar_serializer) for the full list. + +## Defining APIs (`SyncSchema`) + +Root entry points live in `app/models/sync_schema.rb`. A field whose name matches +a model class and takes `ids:` is the **reload API** for that type, used when the +client subscribes by id — put your authorization there. + ```ruby -# app/models/sync_schema.rb class SyncSchema < ArSync::SyncSchemaBase - # User-defined api - serializer_field :my_simple_profile_api do |current_user| + serializer_field :my_profile do |current_user| current_user end - serializer_field :my_simple_friends_api do |current_user, age:| + + serializer_field :my_friends do |current_user, age:| current_user.friends.where(age: age) end - # Reload api (field name = classname, params = `ids:`) + + # Reload APIs (field name = class name, params = `ids:`) serializer_field :User do |current_user, ids:| - User.where(condition).where id: ids + User.where(accessible_condition).where id: ids end + serializer_field :Post do |current_user, ids:| - Post.where(condition).where id: ids + Post.where(accessible_condition).where id: ids end end ``` -3. Write your view -```html - - -