jennifer_twin

Version, currently 0.1.02 versions

github.com/imdrasil/jennifer_twin

Jennifer presenter library

3 stars
2 dependents
License: MIT

Nothing has been indexed for 0.1.0 yet. The tag is recorded, its shard.yml has not been read, so the manifest and dependency list below are empty because they are unknown rather than because they are absent.

Installation

# Add this to your shard.yml
dependencies:
  jennifer_twin:
    github: imdrasil/jennifer_twin
    version: ~> 0.1.0

Then run:

shards install

shard.yml

No shard.yml has been indexed for 0.1.0. You can read it on the repository.

Dependencies

Unknown: the shard.yml for this version has not been read yet.

README

This README is the one indexed from the repository at its latest ref, not from the tag for this version.

JenniferTwin Latest Release

Super simple library to dump/load Jennifer model attributes to plain class instance to be able to integrate it with any kind of hidden attributes.

Installation

  1. Add the dependency to your shard.yml:
dependencies:
  jennifer_twin:
    github: imdrasil/jennifer_twin
    version: 0.1.1
  1. Run shards install

Usage

Jennifer generates some amount of hidden attributes for a mode to be able to track whether attribute has been changed, relation load state or just a collection, etc. For some tasks you would like to have an instance containing only model attributes or it's subset. One of the most popular example - JSON::Serializable. Therefor JenniferTwin copies all data from original instance and store them.

If you trying to solve issue of model serialization to JSON - take a look at Serializer.

To create a twin include JenniferTwin and call .map_fields macro:

require "jennifer_twin"

class UserTwin
  include JenniferTwin

  map_fields User
end

Mapping

.map_fields macro generates only 3 things:

  • getters for all fields named after model's ones (unless other name is specified)
  • initializer accepting model instance to copy
  • #to_model method to create a model instance from it's fields
user = User.all.first
user_twin = UserTwin.new(user)
user_twin.to_model # => User

As a 2nd argument macro accepts named tuple or symbol-based hash of field options. Supported options are:

  • :ignore - if set to true ignores specified field
  • :key - defines attribute with the specified value
  • :annotations - adds annotations above field setter

Let's take a look at more descriptive example:

class User < Jennifer::Model::Base
  mapping(
    id: Primary32,
    name: String?,
    age: Int32?,
    password_hash: String?
  )
end

class UserTwin
  include JenniferTwin
  include JSON::Serializable

  map_fields(User, {
    age: { annotations: [@[JSON::Field(emit_null: true)]] }
    name: { key: :full_name },
    password_hash: { ignore: true }
  })

  setter full_name
end

user = User.all.first # <User:0x000000000010 id: 1, name: "User 8", age: nil, password_hash: "<hash>">
user_twin = UserTwin.new(user) # <UserTwin:0x000000000020 @id=1, @full_name="User 8", @age=nil>
user_twin.to_json # => %({"id":1,"full_name":"User 8","age":null})

user_twin.full_name = "New Name"
user_twin.to_modal # <User:0x000000000030 id: nil, name: "New Name", age: nil, password_hash: nil>

Also you can add additional custom logic to generated initializer passing a block to the macro call. To access model instance use record variable name.

class UserTwin
  include JenniferTwin

  getter full_name : String

  map_fields(User) do
    @full_name = "#{record.name} Snow"
  end
end

Contributing

  1. Fork it (https://github.com/imdrasil/jennifer_twin/fork)
  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 a new Pull Request

Contributors