massive

Massive assignment for haxe.
https://github.com/Montycarlo/massive.hx

To install, run:

haxelib install massive 1.0.2 

See using Haxelib in Haxelib documentation for more information.

README.md

Massive.hx - Mass(ive) assignment for Haxe

Motivation

A lot of modern web frameworks - such as Ruby on Rails1 and Yii22 provide a feature called Mass assignment. It's a convenience feature which maps out an assignment of attributes from one model to another, 'populating' it for a certain scenario.

I dislike writing a bunch of assignment statements consecutively. It feels like a bit of a code smell and I want it to go away. This is more for personal use than anything else.

Solution

A build and initialization macro with some syntax sugar to make your code puurrttyyy~.

Caution!
Using Massive assignment in a improper manner can lead to security vulnerabilities.3 4 5

Usage

Given a model ExampleModel;

class ExampleModel{

  public var propertyA:Int;
  public var propertyB:Int;
  public var propertyC:Int;
  private var propertyD:Int;

  public function new(a:Int,b:Int,c:Int,d:Int){
    this.propertyA = a;
    this.propertyB = b;
    this.propertyC = c;
    this.propertyD = d;
  }

}

and two instances of the model;

var oldModel = new ExampleModel(1, 2, 3, 4);
var newModel = new ExampleModel(3, 4, 10, 55);

Selective Assignment

We can selectively copy attributes from newModel to oldModel;

function example(){
  @:mass(propertyA, propertyB) oldModel = newModel;
}

Which will map out to the following at compile time;

function example(){
  oldModel.propertyA = newModel.propertyA;
  oldModel.propertyB = newModel.propertyB;
}

Absolute Assignment

We can also copy all public writable attributes from newModel to oldModel that oldModel can hold;

@:mass function example(){
  @:mass oldModel = newModel;
}

Which will map out to the following at compile time;

function example(){
  oldModel.propertyA = newModel.propertyA;
  oldModel.propertyB = newModel.propertyB;
  oldModel.propertyC = newModel.propertyC;
}

Scenarios

Scenarios are an addition to massive assignment, traditionally to work with ActiveRecord instances or instances of a model from the database. They are an attempt to simultaneously 'raise' the abstraction level by defining the whitelisted attributes in the class model, so you can reuse the whitelists across multiple @:mass assignments, and to coerce the programmer to explicitly define what attributes are 'safe' in a certain context.

The scenario implementation assumes that your ExampleModel has a function public inline function scenario():Map<String,Array<String>>. Inlining isn't mandatory but there's no reason not to.

class ExampleModel{
  ...
  public inline function scenario() return [
    "exampleScenario" => ["propertyB", "propertyC"]
  ];
  ...
}

Then, when you want to assign to a ExampleModel instance in a constrained monomorph, ie an explicit ExampleModel instance, use a @:scenario("scenario") in a parent node of the AST, ie a function;

@:scenario("exampleScenario") function closure(){
  @:mass oldModel = newModel;
}

Which will then map to (roughly) the following code using Reflection;

function closure(){
  for(p in ["propertyB", "propertyC"]){
    var val = Reflect.getProperty(newModel, p);
    Reflect.setProperty, oldModel, p, val);
  }
}

Credits

A big thankyou to back2dos for the tink libraries - they are extremely useful and this language extension was based off of the tink_await library.

TODO

  • Check at compiletime if object B has all props from object A?
  • Only update props from B that intersect with A, warn otherwise
  • Allow assignment to anonymous structures
  • Allow assignment from anonymous structures
  • public readable check for getting vals from B
Contributors
epidevJosh
Version
1.0.2
Published
9 years ago
License
MIT

All libraries are free

Every month, more than a thousand developers use Haxelib to find, share, and reuse code — and assemble it in powerful new ways. Enjoy Haxe; It is great!

Explore Haxe

Haxe Manual

Haxe Code Cookbook

Haxe API documentation

You can try Haxe in the browser! try.haxe.org

Join us on GitHub!

Haxe is being developed on GitHub. Feel free to contribute or report issues to our projects.

Haxe on GitHub