Properties would not be really fun if you could not add new properties to your instances depending on what the object does. First define the roles:
@picture = Property::Role.new do |p| p.integer :width, :default => :get_width p.integer :height, :default => :get_height p.string 'camera' p.string 'location' p.actions do # Define new methods to insert into model def get_width image.width end def get_height image.height end def image raise 'Missing file' unless @file @image ||= ImageBuilder(@file) end end end
And then, either when creating new pictures or updating them, you need to include the role:
@model.has_role @picture
The model now has the picture’s properties defined, with accessors like model.camera
, methods like model.image
, get_with, etc and default values will be fetched on save.
Note that you do not need to include a role just to read the data as long as you use the ‘prop’ accessor.
Finally if you can store and retrieve a Property::Role
from the database by using Property::StoredRole
.
in Zena
In Zena, the roles are defined through an interface along with Virtual Classes. Roles are “attached” to a (virtual) class. This means that roles are a little like modules in Ruby with some differences.
First, the roles are all “included” in the model only during write operations or Zafu compilation to check for the existence of property attributes. This does not mean you do not have access to the properties though ! You just read them through the prop['...']
accessor.
Second, every node keeps a record of the used roles (the ones that have non-blank values). This can be used to filter in Zafu templates. Example with a “Worker” role:
<r:Worker> show attributes specific to workers </r:Worker>
Zena also keeps an index of what nodes plays what role thus enabling you to find all “things” in your site that act like “Worker”, “Product”, “Task”, etc.
You can use the “relation” filter:
workers in site
Or even use it in where clauses:
nodes where role = Worker in site
In fact the two examples above produce the exact same SQL.