Skip to content
This repository was archived by the owner on Oct 19, 2018. It is now read-only.

Representable

Michael edited this page Jan 9, 2017 · 2 revisions

For example:

From @MichaelSp

class Project 
   include HyperLoop::Model
   hyper_attributes :name, :a, :b, :c 
   # or if types can't be deduced
  hyper_attributes name: :string, a: :integer, b: AnotherModel, c: Hash
  
  # most of time you are going to want to specify how to load, and update 
  # typically via some API
  on_create do
    my.fancy.persistence.logic
  end
  on_read :fetch_the_object
  on_update :do_stuff
  on_destroy { my.fancy.destroy.logic }
end

It seems like a lot of the DSL is already working great in this gem: http://trailblazer.to/gems/representable/3.0/api.html so why make use of it under the hood then you can do this:

class Project 
  include HyperLoop::Model 
  property :name
  property :a
  property :some_string, as: 'SomeString'
  property :recorded_at, type: DateTime, default: "May 12th, 2012"
  # and on and on...
  # however to make things more consistent with AR we add belongs_to, has_many, etc
  has_many :applications
  # use property definitions to define reader/writers
  include HyperLoop::Model::JSON
  # now you have to_json, and from_json that uses above property definitions (like Representable)
  on_create do
   my.fancy.persitence.logic as_json # as_json will use property info to create json (like Representable)
  end
  on_read do
    from_json(my.fancy.fetch_logic) #parse and initialize properties (like Representable)
  end
end

The only problem I see with this is that instead of "decorating" our project model we are messing with it. So how about this:

class ProjectMap < HyperLoop::ModelMap
  # by default will deduce class name as Project (like Pundit Policies)
  # all the declarations go here .. instead of polluting the Project model
  # if no Project class is found, that's fine we will create an empty one for you
end

But after writing all this, I am feeling like so what???

Can we just do this with our new "Operations"???

class Project
   ... whatever this looks like
end

class LoadProject < HyperMesh::Operation
  param :id
  allow_remote_access
  def execute
    # go get your data from the API and return it probably verifying acting_user is correct
  end
end

Here is the problem: LoadProject will want to be called from the client, but run on the server, which works fine, but we will need to make sure that we can easily marshall / unmarshall arbitrary ruby objects over the "wire". In the above case LoadProject will go get some json data from an API, then build a ruby structure, and then we need HyperMesh::Operation to re-json-ize it and send to the client, which will then rebuild it!

Need to think more on this (i.e. does Representable just run on the client) and the server operation just fetches the raw json and passes it down??

MichaelSp: I'd still prefer the first and second example. And I think it's necessary to run parts of the model logic on the server. Given a large JSON file and I only want parts of that transferred to the client, server side methods are the only way to reduce the data size. I'm not completely familiar with what operations can do, but I think using on operation for each persistence method (create, read, update, delete) is not the right way.

Clone this wiki locally