<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Hartmut B.</title>
    <description>The latest articles on DEV Community by Hartmut B. (@topofocus).</description>
    <link>https://dev.to/topofocus</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F189171%2Fa374b702-1725-49b2-a5a8-dbfb15dbe9ed.png</url>
      <title>DEV Community: Hartmut B.</title>
      <link>https://dev.to/topofocus</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/topofocus"/>
    <language>en</language>
    <item>
      <title>ArcadeDB, Ruby &amp;&amp; Jupyter</title>
      <dc:creator>Hartmut B.</dc:creator>
      <pubDate>Fri, 19 Jan 2024 07:08:31 +0000</pubDate>
      <link>https://dev.to/topofocus/arcadedb-ruby-jupyter-egf</link>
      <guid>https://dev.to/topofocus/arcadedb-ruby-jupyter-egf</guid>
      <description>&lt;p&gt;Jupyter Notebooks are widely used in data science, scientific computing, and machine learning due to their interactive nature and ability to present code, results, and explanations in a clear and organized manner. The &lt;a href="https://github.com/SciRuby/iruby"&gt;IRuby Project&lt;/a&gt; introduces a modern ruby kernel to jupyter and opens the environment for ruby projects.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/topofocus/arcadedb"&gt;The ArcadeDB Ruby Interface&lt;/a&gt; naively supports iruby jupyter notebooks.&lt;/p&gt;

&lt;p&gt;To activate include both gems in the Gemfile&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="c1"&gt;## Gemfile&lt;/span&gt;
&lt;span class="n"&gt;gem&lt;/span&gt; &lt;span class="s1"&gt;'arcadedb'&lt;/span&gt;
&lt;span class="n"&gt;gem&lt;/span&gt; &lt;span class="s1"&gt;'iruby'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Jupyter-output is realized through &lt;code&gt;IRuby.display, IRuby.html&lt;/code&gt; and &lt;code&gt;IRuby.table&lt;/code&gt;-commands in the &lt;code&gt;to_html&lt;/code&gt;-method of the class to be supported. &lt;code&gt;ArcadeDB&lt;/code&gt;-database objects inherit this &lt;code&gt;to_html&lt;/code&gt;-implementation&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;to_html&lt;/span&gt;  &lt;span class="c1"&gt;# iruby&lt;/span&gt;
  &lt;span class="n"&gt;the_rid&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"[&lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="n"&gt;rid&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;] : {&lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="nb"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;in&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;count&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;-&amp;gt;}{-&amp;gt;&lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="nb"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;out&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;count&lt;/span&gt; &lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;}"&lt;/span&gt;
  &lt;span class="no"&gt;IRuby&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;display&lt;/span&gt; &lt;span class="no"&gt;IRuby&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;html&lt;/span&gt; &lt;span class="s2"&gt;"&amp;lt;b&amp;gt;&lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="nb"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;class&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;&amp;lt;/b&amp;gt;&lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="n"&gt;the_rid&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; &amp;lt; &lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="n"&gt;html_attributes&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;map&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;_&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;v&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;  &lt;span class="n"&gt;v&lt;/span&gt; &lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;.join(', ')} &amp;gt;"&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;which leads to the following output&lt;/p&gt;

&lt;blockquote&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Member.find name: ‘Gross’ &lt;br&gt; 
&lt;span&gt;&lt;b&gt;Member&lt;/b&gt;[#49:43] : {0-&amp;gt;}{-&amp;gt;0}&lt;/span&gt; &amp;lt; Frau, Maria, Gross, Lüneburg, Hauptstr. 12a &amp;gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  Customization
&lt;/h3&gt;

&lt;p&gt;The default output is defined by&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;html_attributes&lt;/span&gt;  &lt;span class="c1"&gt;# Standard&lt;/span&gt;
  &lt;span class="n"&gt;invariant_attributes&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It includes all properties except &lt;code&gt;created_at&lt;/code&gt; and &lt;code&gt;modified_at&lt;/code&gt;. Customization is straightforward:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;html_attributes&lt;/span&gt;  &lt;span class="c1"&gt;# model/arcade/member.rb&lt;/span&gt;
 &lt;span class="p"&gt;{&lt;/span&gt;     &lt;span class="no"&gt;Sex&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="ss"&gt;:sex&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
   &lt;span class="no"&gt;Vorname&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="ss"&gt;:surname&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="no"&gt;Name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="ss"&gt;:name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
       &lt;span class="no"&gt;Ort&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="ss"&gt;:town&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="no"&gt;Stra&lt;/span&gt;&lt;span class="err"&gt;ß&lt;/span&gt;&lt;span class="ss"&gt;e: :street&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; 
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This affects the output of tables, too. &lt;br&gt;
&lt;code&gt;Member.where&lt;/code&gt; returns an array and triggers the expected jupyter-output:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Member.where name: ‘Gross’ &lt;br&gt;&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;&lt;tbody&gt;
            &lt;tr&gt;
&lt;td&gt;Sex&lt;/td&gt;
&lt;td&gt;Vorname&lt;/td&gt;
&lt;td&gt;Name&lt;/td&gt;
&lt;td&gt;Ort&lt;/td&gt;
&lt;td&gt;Straße&lt;/td&gt;
&lt;/tr&gt;
      &lt;tr&gt;
&lt;td&gt;Frau&lt;/td&gt;
&lt;td&gt;Maria&lt;/td&gt;
&lt;td&gt;Gross&lt;/td&gt;
&lt;td&gt;Lüneburg&lt;/td&gt;
&lt;td&gt;Hauptstr. 12a&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Advanced Visualization &amp;amp;&amp;amp; Calculations
&lt;/h3&gt;

&lt;p&gt;The ecosystem of applications supporting jupyter notebooks is slowly growing. Visualizations of any kind are realized with the excellent &lt;a href="https://github.com/ankane/vega-ruby"&gt;vega&lt;/a&gt; gem. Jupyter notebooks are supported. &lt;/p&gt;

&lt;p&gt;ArcadeDB database contents are easily exported to &lt;a href="https://github.com/ankane/polars-ruby"&gt;polars dataframes&lt;/a&gt;. &lt;/p&gt;

&lt;p&gt;A typical workflow would be to use &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://github.com/topofocus/arcadedb"&gt;arcadedb&lt;/a&gt; to store and easily retrieve the data, &lt;/li&gt;
&lt;li&gt;export them to &lt;a href="https://github.com/ankane/polars-ruby"&gt;polars dataframes&lt;/a&gt;, perform extensive calculations and use &lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/ankane/vega-ruby"&gt;vega&lt;/a&gt; for visualization. &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The ruby script runs in a python environment, uses a java-based database for storage, a rust-powered Dataframe-Engine for calculations and a javascript library to present the results. &lt;/p&gt;




&lt;p&gt;To experiment with this environment in jupyter, the &lt;a href="https://github.com/topofocus/dev-adventures"&gt;Github respiratory&lt;/a&gt; from  the &lt;a href="https://dev.to/topofocus/ruby-adventures-with-aradedb-45em"&gt;Ruby Adventures with ArcadeDB Series&lt;/a&gt; contains an &lt;code&gt;iruby&lt;/code&gt; directory. &lt;br&gt;
Clone it, install &lt;code&gt;Jupyter&lt;/code&gt; and ìruby&lt;code&gt;, go to the&lt;/code&gt;iruby&lt;code&gt;-directory and enter&lt;/code&gt;juypter notebook` to start Jupyter in the standard browser. Enjoy!&lt;/p&gt;

</description>
      <category>arcadedb</category>
      <category>ruby</category>
      <category>iruby</category>
      <category>jupyter</category>
    </item>
    <item>
      <title>Ruby Adventures with ArcadeDB 2</title>
      <dc:creator>Hartmut B.</dc:creator>
      <pubDate>Mon, 11 Dec 2023 17:27:20 +0000</pubDate>
      <link>https://dev.to/topofocus/ruby-adventures-with-arcadedb-2-534k</link>
      <guid>https://dev.to/topofocus/ruby-adventures-with-arcadedb-2-534k</guid>
      <description>&lt;p&gt;&lt;strong&gt;note:&lt;/strong&gt; Clone the git respiratory  &lt;a href="https://github.com/topofocus/dev-adventures"&gt;https://github.com/topofocus/dev-adventures&lt;/a&gt; to play with the data. &lt;strong&gt;:end-note&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Part One:  &lt;a href="https://dev.to/topofocus/ruby-adventures-with-aradedb-45em"&gt;Ruby Adventures with ArcadeDB&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Some Basics
&lt;/h2&gt;

&lt;p&gt;ActiveRecord is the standard abstraction layer for databases in ruby. It translates ruby code to SQL, optimizes queries and is compatible to many low level database drivers. Its promise: You don't have to know anything about databases, can use every relational database – everywhere. Just stick to ruby code. &lt;/p&gt;

&lt;p&gt;Relational databases are a popular way to organize structured data. But data sets aren't always neatly organized. Sometimes, the data is forced into a mold that doesn't fit just because the tool requires it.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://arcadedb.com"&gt;ArcadeDB&lt;/a&gt; is a modern multi model database. Its promise is analogous  to ActiveRecord: Whatever the structure of your data is, the database offers an effective host. The &lt;a href="https://github.com/topofocus/arcadedb"&gt;ruby-interface to ArcadeDB&lt;/a&gt; aims to combine the &lt;br&gt;
user friendlines of ActiveRecord and the flexibility of ArcadeDB. &lt;/p&gt;
&lt;h2&gt;
  
  
  The Power of RID
&lt;/h2&gt;

&lt;p&gt;Relational Databases organize data in tables. Very often, a column is called &lt;code&gt;id&lt;/code&gt; and carries the index.  &lt;a href="https://arcadedb.com"&gt;ArcadeDB&lt;/a&gt; too has tables. They're called &lt;code&gt;types&lt;/code&gt; and carry object-oriented behaviors.  In addition the local data-structure can always inspected via &lt;code&gt;RID&lt;/code&gt;'s. &lt;br&gt;
This is happening:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;code&gt;select from #1:0&lt;/code&gt;&lt;br&gt;&lt;br&gt;
{:&lt;a class="mentioned-user" href="https://dev.to/rid"&gt;@rid&lt;/a&gt;=&amp;gt;"#449:0", :@type=&amp;gt;"human", :&lt;a class="mentioned-user" href="https://dev.to/cat"&gt;@cat&lt;/a&gt;=&amp;gt;"v", :name=&amp;gt;"hugo }   &lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The &lt;code&gt;RID&lt;/code&gt; exposes itself as &lt;code&gt;human&lt;/code&gt;-type, its a vertex (&lt;a class="mentioned-user" href="https://dev.to/cat"&gt;@cat&lt;/a&gt;: "v") and has a property &lt;code&gt;name&lt;/code&gt;. &lt;/p&gt;

&lt;p&gt;The &lt;a href="https://github.com/topofocus/arcadedb"&gt;ruby-interface&lt;/a&gt;  connects the @type to an appropriate &lt;code&gt;Model class&lt;/code&gt;, assigns the database properties to corresponding model-attributes and exposes the data to customized model-methods. &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Its much simpler to access pieces of data from ArcadeDB then from any relational database. &lt;a href="https://arcadedb.com"&gt;ArcadeDB&lt;/a&gt; is a native object database, no abstraction is needed to fit the data representation in the database to the data-model in your ruby program. &lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2&gt;
  
  
  Exploring the Structure
&lt;/h2&gt;

&lt;p&gt;The &lt;code&gt;Account&lt;/code&gt;-Type is a vertex. This implies, it might have edges, that connect it to other vertices. This is explored with the &lt;code&gt;nodes&lt;/code&gt;-method&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;first_human&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;  &lt;span class="no"&gt;DB&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;      &lt;span class="c1"&gt;# select from #1:0&lt;/span&gt;
&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;human&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="c1"&gt;#1:0]:{0-&amp;gt;}{-&amp;gt;1}, name: hugo&amp;gt;] &lt;/span&gt;
&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;first_account&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;nodes&lt;/span&gt;              &lt;span class="c1"&gt;# select both() from #1:0&lt;/span&gt;
&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;human&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="c1"&gt;#2:0]:{1-&amp;gt;}{-&amp;gt;0}, name: berta&amp;gt;] &lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A connected &lt;code&gt;Account&lt;/code&gt;-record is retrieved!&lt;/p&gt;

&lt;h2&gt;
  
  
  Bidirectional connections – with attributes
&lt;/h2&gt;

&lt;p&gt;Lets design a simple relation&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--abOSpvJe--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/w1jdkresj07aire4t65j.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--abOSpvJe--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/w1jdkresj07aire4t65j.jpg" alt="Image description" width="639" height="90"&gt;&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;first_account&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;assign&lt;/span&gt; &lt;span class="ss"&gt;via: &lt;/span&gt;&lt;span class="no"&gt;IsMarriedTo&lt;/span&gt;
                        &lt;span class="ss"&gt;to: &lt;/span&gt;&lt;span class="n"&gt;second_account&lt;/span&gt;
                      &lt;span class="ss"&gt;date: &lt;/span&gt;&lt;span class="no"&gt;Date&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="mi"&gt;1955&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;12&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;21&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
                      &lt;span class="ss"&gt;town: &lt;/span&gt;&lt;span class="s2"&gt;"Dublin"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If -- by convention -- outgoing connections belong to the male and incoming one to the female, a query of Human's which got &lt;code&gt;out&lt;/code&gt;-connections of type &lt;code&gt;IsMarriedTo&lt;/code&gt;, loads a list of married man. Compare that to efforts needed with relational databases. &lt;/p&gt;

&lt;p&gt;Its possible to use the &lt;code&gt;node&lt;/code&gt;-method here, too. &lt;br&gt;
But ArcadeDB offers a versatile alternative.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Arcade::Match.new( type: Human, as: :h)
             .out( IsMarriedTo )
             .execute { "h.rid, h.name" }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;Arcade::Match&lt;/code&gt; is a simple wrapper of the &lt;a href="https://docs.arcadedb.com/#SQL-Match"&gt;Match Statement&lt;/a&gt;, which »queries the database in a declarative manner, using pattern matching (inspired by Cypher)«.&lt;br&gt;
The compiled match statement looks like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;MATCH { type: human, as: h }
      .out( 'is_married_to')
RETURN h.rid, h.name
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;and returns an array with all rid's and names of the suspects.&lt;br&gt;&lt;br&gt;
The query is easily extended to only marriages in the last decade of the 20th century:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="no"&gt;Arcade&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;Match&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="ss"&gt;type: &lt;/span&gt;&lt;span class="no"&gt;Human&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;as: :h&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
             &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;out&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="no"&gt;IsMarriedTo&lt;/span&gt; &lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;where: &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="ss"&gt;date: &lt;/span&gt;&lt;span class="mi"&gt;1990&lt;/span&gt; &lt;span class="o"&gt;..&lt;/span&gt; &lt;span class="mi"&gt;2000&lt;/span&gt;&lt;span class="p"&gt;})&lt;/span&gt;
             &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;execute&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="s2"&gt;"h.rid, h.name"&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="no"&gt;MATCH&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="ss"&gt;type: &lt;/span&gt;&lt;span class="n"&gt;human&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;as: &lt;/span&gt;&lt;span class="n"&gt;h&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
      &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;out&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="s1"&gt;'is_married_to'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;where: &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="n"&gt;date&lt;/span&gt; &lt;span class="n"&gt;between&lt;/span&gt; &lt;span class="mi"&gt;1990&lt;/span&gt; &lt;span class="ow"&gt;and&lt;/span&gt; &lt;span class="mi"&gt;2000&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="no"&gt;RETURN&lt;/span&gt; &lt;span class="n"&gt;h&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;rid&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;h&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;name&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The properties on the bidirectional connection(edge) are essential to this query. &lt;/p&gt;

&lt;p&gt;ArcadeDB is not only a object-database regarding to the data-storage but to the connections between the data itself. &lt;br&gt;
If a couple divorces, the &lt;code&gt;IsMarriedTo&lt;/code&gt;connection is replaced by a &lt;code&gt;IsDivorced&lt;/code&gt;-edge. Both edge-classes are childs of &lt;code&gt;IsFriend&lt;/code&gt; Edges. &lt;/p&gt;

&lt;p&gt;Until now, this example lacks realism, as same-sex marriages are not allowed (Only man have &lt;code&gt;out&lt;/code&gt;-connections). This can easily be addressed via inheritance.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--bpemsMZD--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/4of0kr1arbs24v8d7my1.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--bpemsMZD--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/4of0kr1arbs24v8d7my1.jpg" alt="Image description" width="677" height="254"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The final setup of the database looks as following&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="no"&gt;DB&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;Arcade&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;Init&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;db&lt;/span&gt;  &lt;span class="c1"&gt;# Reference to the database&lt;/span&gt;
&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="no"&gt;Male&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="no"&gt;Female&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="no"&gt;IsMarriedTo&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="no"&gt;IsDivorced&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nf"&gt;each&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;y&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;y&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;create_type&lt;/span&gt;  &lt;span class="p"&gt;}&lt;/span&gt;  
&lt;span class="c1"&gt;# Inheritance is respected, `Human` and `IsFriend` are allocated implicitly&lt;/span&gt;

&lt;span class="n"&gt;hugo&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;paul&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;jochen&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'Hugo'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'Paul'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'Jochen'&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nf"&gt;map&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;man&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;
   &lt;span class="no"&gt;Male&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;insert&lt;/span&gt; &lt;span class="ss"&gt;name: &lt;/span&gt;&lt;span class="n"&gt;man&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="n"&gt;berta&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;hilde&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;maria&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'Berta'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'Hilde'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'Maria'&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nf"&gt;map&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;woman&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;
   &lt;span class="no"&gt;Female&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;insert&lt;/span&gt; &lt;span class="ss"&gt;name: &lt;/span&gt;&lt;span class="n"&gt;woman&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="n"&gt;hugo&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;assign&lt;/span&gt; &lt;span class="ss"&gt;via: &lt;/span&gt;&lt;span class="no"&gt;IsMarriedTo&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;town: &lt;/span&gt;&lt;span class="s1"&gt;'Duesseldorf'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;date: &lt;/span&gt;&lt;span class="no"&gt;Date&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1956&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;12&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="ss"&gt;to: &lt;/span&gt;&lt;span class="n"&gt;berta&lt;/span&gt;
&lt;span class="n"&gt;paul&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;assign&lt;/span&gt; &lt;span class="ss"&gt;via: &lt;/span&gt;&lt;span class="no"&gt;IsDivorced&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;date: &lt;/span&gt;&lt;span class="no"&gt;Date&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1959&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="ss"&gt;to: &lt;/span&gt;&lt;span class="n"&gt;hilde&lt;/span&gt;
&lt;span class="n"&gt;maria&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;assign&lt;/span&gt; &lt;span class="ss"&gt;via: &lt;/span&gt;&lt;span class="no"&gt;IsFriend&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;to: &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt; &lt;span class="n"&gt;jochen&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;hilde&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;hugo&lt;/span&gt; &lt;span class="p"&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Verify the data structure&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="no"&gt;Human&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;all&lt;/span&gt;
&lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;male&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="c1"&gt;#66:0]:{1-&amp;gt;}{-&amp;gt;1}, name: Hugo&amp;gt;,                 &lt;/span&gt;
    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;male&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="c1"&gt;#69:0]:{0-&amp;gt;}{-&amp;gt;1}, name: Paul&amp;gt;,                 &lt;/span&gt;
    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;male&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="c1"&gt;#72:0]:{1-&amp;gt;}{-&amp;gt;0}, name: Jochen&amp;gt;,&lt;/span&gt;
  &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;female&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="c1"&gt;#90:0]:{1-&amp;gt;}{-&amp;gt;0}, name: Berta&amp;gt;,&lt;/span&gt;
  &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;female&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="c1"&gt;#93:0]:{2-&amp;gt;}{-&amp;gt;0}, name: Hilde&amp;gt;,&lt;/span&gt;
  &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;female&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="c1"&gt;#96:0]:{0-&amp;gt;}{-&amp;gt;3}, name: Maria&amp;gt;]&lt;/span&gt;

&lt;span class="no"&gt;Female&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;find&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="ss"&gt;name: &lt;/span&gt;&lt;span class="s1"&gt;'Maria'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;out&lt;/span&gt;
&lt;span class="o"&gt;=&amp;gt;&lt;/span&gt;                                                                 
&lt;span class="p"&gt;[&lt;/span&gt;  &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;male&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="c1"&gt;#66:0]:{1-&amp;gt;}{-&amp;gt;1}, name: Hugo&amp;gt;,                              &lt;/span&gt;
 &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;female&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="c1"&gt;#93:0]:{2-&amp;gt;}{-&amp;gt;0}, name: Hilde&amp;gt;,                           &lt;/span&gt;
   &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;male&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="c1"&gt;#72:0]:{1-&amp;gt;}{-&amp;gt;0}, name: Jochen&amp;gt;]&lt;/span&gt;

&lt;span class="c1"&gt;# query for divorced couples&lt;/span&gt;
&lt;span class="no"&gt;Arcade&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;Match&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="ss"&gt;type: &lt;/span&gt;&lt;span class="no"&gt;Human&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;as: &lt;/span&gt;&lt;span class="n"&gt;m&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
             &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;out&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="no"&gt;IsDivorced&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
             &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;node&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="ss"&gt;as: :f&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
             &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;execute&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="s2"&gt;"m.name, f.name"&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="no"&gt;INFO&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="no"&gt;Q&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="no"&gt;MATCH&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="ss"&gt;type: &lt;/span&gt;&lt;span class="n"&gt;human&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;as: &lt;/span&gt;&lt;span class="n"&gt;m&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
                &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;out&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'is_divorced'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
               &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="ss"&gt;as: &lt;/span&gt;&lt;span class="n"&gt;f&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; 
         &lt;span class="no"&gt;RETURN&lt;/span&gt; &lt;span class="n"&gt;m&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;name&lt;/span&gt; 
 &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt;                                                                                                          
&lt;span class="p"&gt;[{&lt;/span&gt;&lt;span class="ss"&gt;:m&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;name&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt;&lt;span class="s2"&gt;"Paul"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:f&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;name&lt;/span&gt;&lt;span class="o"&gt;=&amp;gt;&lt;/span&gt;&lt;span class="s2"&gt;"Hilde"&lt;/span&gt;&lt;span class="p"&gt;}]&lt;/span&gt;  
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;( to be continued ... )&lt;/p&gt;

</description>
      <category>ruby</category>
      <category>nosql</category>
      <category>orm</category>
      <category>arcadedb</category>
    </item>
    <item>
      <title>Ruby Adventures with ArcadeDB</title>
      <dc:creator>Hartmut B.</dc:creator>
      <pubDate>Wed, 25 Oct 2023 14:39:01 +0000</pubDate>
      <link>https://dev.to/topofocus/ruby-adventures-with-aradedb-45em</link>
      <guid>https://dev.to/topofocus/ruby-adventures-with-aradedb-45em</guid>
      <description>&lt;p&gt;&lt;a href="https://arcadedb.com"&gt;ArcadeDB&lt;/a&gt; is a modern, multi purpose Not-Only-SQL database. The &lt;a href="https://github.com/topofocus/arcadedb"&gt;ArcadeDB-Gem&lt;/a&gt; opens the database for ruby-projects. &lt;/p&gt;

&lt;p&gt;The database is organized with &lt;code&gt;types&lt;/code&gt;. A database-type is either a &lt;code&gt;document&lt;/code&gt;, a &lt;code&gt;vertex&lt;/code&gt; or an &lt;code&gt;edge&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Similar to other database-adapters in ruby, &lt;code&gt;types&lt;/code&gt; are declared in the model directory of the project. &lt;/p&gt;

&lt;p&gt;A typical &lt;code&gt;Account&lt;/code&gt;-model is similar to a rudimentary &lt;code&gt;ActiveRecord&lt;/code&gt;-based Model-setup.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="k"&gt;module&lt;/span&gt; &lt;span class="nn"&gt;Arcade&lt;/span&gt;
  &lt;span class="k"&gt;class&lt;/span&gt;  &lt;span class="nc"&gt;Account&lt;/span&gt;  &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="no"&gt;Arcade&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;Vertex&lt;/span&gt;
    &lt;span class="n"&gt;attribute&lt;/span&gt; &lt;span class="ss"&gt;:name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="no"&gt;Types&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;Nominal&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;String&lt;/span&gt;
    &lt;span class="n"&gt;attribute&lt;/span&gt; &lt;span class="ss"&gt;:mail&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="no"&gt;Types&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;Nominal&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;String&lt;/span&gt;

    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nc"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;db_init&lt;/span&gt;
      &lt;span class="no"&gt;File&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;read&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kp"&gt;__FILE__&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;gsub&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sr"&gt;/.*__END__/m&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;''&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="cp"&gt;__END__
CREATE PROPERTY account.name STRING
CREATE INDEX  ON account (name) UNIQUE
## /model/arcade/account.rb
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Account is a &lt;code&gt;Vertex&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Two attributes are predefined and type-checked via DRY::Types. &lt;/li&gt;
&lt;li&gt;One Index is defined. Its needed for filtering.&lt;/li&gt;
&lt;li&gt;The code at the bottom of the model-file creates the corresponding database-properties through -&amp;gt; &lt;code&gt;Account.create_type&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  First steps
&lt;/h2&gt;

&lt;p&gt;It is assumed, that an &lt;a href="https://docs.arcadedb.com/#_run-arcadedb"&gt;arcadedb-server&lt;/a&gt; is setup and running.&lt;br&gt;
Initialize a ruby project&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;mkdir test-project &amp;amp;&amp;amp; cd test-project
mkdir bin
mkdir model; mkdir model/arcade
bundle init
bundle add arcadedb
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Clone &lt;a href="https://github.com/topofocus/dev-adventures"&gt;dev-adventures&lt;/a&gt; and modify the provides framework to your needs.&lt;/strong&gt; Modify the provided arcade.yml!&lt;/p&gt;

&lt;p&gt;Open the console &lt;code&gt;cd bin &amp;amp;&amp;amp; ./console&lt;/code&gt; and create the Account-Vertex&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="mf"&gt;3.2&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mo"&gt;002&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="no"&gt;Account&lt;/span&gt;
 &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="no"&gt;Arcade&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;Account&lt;/span&gt; 
&lt;span class="mf"&gt;3.2&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mo"&gt;003&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="no"&gt;Account&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;create_type&lt;/span&gt;
&lt;span class="mf"&gt;25.10&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;15&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;51&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;50&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="no"&gt;INFO&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="no"&gt;Q&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;create&lt;/span&gt; &lt;span class="n"&gt;vertex&lt;/span&gt; &lt;span class="n"&gt;type&lt;/span&gt; &lt;span class="n"&gt;account&lt;/span&gt;    
&lt;span class="mf"&gt;25.10&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;15&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;51&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;50&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="no"&gt;INFO&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="no"&gt;Q&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="no"&gt;CREATE&lt;/span&gt; &lt;span class="no"&gt;PROPERTY&lt;/span&gt; &lt;span class="n"&gt;account&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;name&lt;/span&gt; &lt;span class="no"&gt;STRING&lt;/span&gt;
&lt;span class="mf"&gt;25.10&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;15&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;51&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;50&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="no"&gt;INFO&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="no"&gt;Q&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="no"&gt;CREATE&lt;/span&gt; &lt;span class="no"&gt;INDEX&lt;/span&gt;  &lt;span class="no"&gt;ON&lt;/span&gt; &lt;span class="n"&gt;account&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;name&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="no"&gt;UNIQ&lt;/span&gt;
&lt;span class="mf"&gt;3.2&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mo"&gt;004&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="no"&gt;Account&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;insert&lt;/span&gt; &lt;span class="ss"&gt;name: &lt;/span&gt;&lt;span class="s1"&gt;'hugo'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;mail: &lt;/span&gt;&lt;span class="s1"&gt;'hugo@test.com'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;age: &lt;/span&gt;&lt;span class="mi"&gt;37&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;home: &lt;/span&gt;&lt;span class="s1"&gt;'0098 565 4433'&lt;/span&gt; 
 &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;account&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="c1"&gt;#1:0]:{0-&amp;gt;}{-&amp;gt;0}, age: 37, home: 0098 565 4433, mail: hugo@test.com, name: hugo&amp;gt; &lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Congratulations! You just created the first record. Only essential attributes are predefined. Other attributes are added as needed. &lt;/p&gt;

&lt;h2&gt;
  
  
  Basic commands
&lt;/h2&gt;

&lt;p&gt;At that point, any &lt;a href="https://docs.arcadedb.com/#SQL"&gt;database query&lt;/a&gt; can be submitted via &lt;code&gt;DB.query "query"&lt;/code&gt; or &lt;code&gt;DB.execute { "query" }&lt;/code&gt;, eg.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt; &lt;span class="no"&gt;DB&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;query&lt;/span&gt; &lt;span class="s1"&gt;'select from account'&lt;/span&gt;
 &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt;                                                
&lt;span class="p"&gt;[{&lt;/span&gt;&lt;span class="ss"&gt;:@rid&lt;/span&gt;&lt;span class="o"&gt;=&amp;gt;&lt;/span&gt;&lt;span class="s2"&gt;"#1:0"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;                                  
  &lt;span class="ss"&gt;:@type&lt;/span&gt;&lt;span class="o"&gt;=&amp;gt;&lt;/span&gt;&lt;span class="s2"&gt;"account"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;                               
  &lt;span class="ss"&gt;:@cat&lt;/span&gt;&lt;span class="o"&gt;=&amp;gt;&lt;/span&gt;&lt;span class="s2"&gt;"v"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;                                      
  &lt;span class="ss"&gt;:mail&lt;/span&gt;&lt;span class="o"&gt;=&amp;gt;&lt;/span&gt;&lt;span class="s2"&gt;"hugo@test.com"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;                          
  &lt;span class="ss"&gt;:name&lt;/span&gt;&lt;span class="o"&gt;=&amp;gt;&lt;/span&gt;&lt;span class="s2"&gt;"hugo"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;                                   
  &lt;span class="ss"&gt;:age&lt;/span&gt;&lt;span class="o"&gt;=&amp;gt;&lt;/span&gt;&lt;span class="mi"&gt;37&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;                                        
  &lt;span class="ss"&gt;:home&lt;/span&gt;&lt;span class="o"&gt;=&amp;gt;&lt;/span&gt;&lt;span class="s2"&gt;"0098 565 4433"&lt;/span&gt;&lt;span class="p"&gt;}]&lt;/span&gt;  
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Most common tasks are present via ruby, eg.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;  &lt;span class="no"&gt;Account&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;find&lt;/span&gt; &lt;span class="ss"&gt;name: &lt;/span&gt;&lt;span class="s1"&gt;'hugo'&lt;/span&gt; &lt;span class="c1"&gt;# find one record&lt;/span&gt;
&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;update&lt;/span&gt; &lt;span class="ss"&gt;name: &lt;/span&gt;&lt;span class="s1"&gt;'danzig'&lt;/span&gt;        &lt;span class="c1"&gt;# does not modify a&lt;/span&gt;
&lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;refresh&lt;/span&gt;                  &lt;span class="c1"&gt;# mutate a&lt;/span&gt;
&lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;account&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="c1"&gt;#1:0]:{0-&amp;gt;}{-&amp;gt;0}, age: 37, home: 0098 565 4433, mail: hugo@test.com, name: danzig&amp;gt; &lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is the first part of an introduction series on ArcadeDB.&lt;/p&gt;

&lt;p&gt;Next Part: &lt;a href="https://dev.to/topofocus/ruby-adventures-with-arcadedb-2-534k"&gt;Ruby Adventures with ArcadeDB 2&lt;/a&gt;&lt;/p&gt;

</description>
      <category>ruby</category>
      <category>nosql</category>
      <category>orm</category>
      <category>arcadedb</category>
    </item>
    <item>
      <title>Tailwind Carousel in Rails 7</title>
      <dc:creator>Hartmut B.</dc:creator>
      <pubDate>Tue, 15 Mar 2022 20:53:11 +0000</pubDate>
      <link>https://dev.to/topofocus/tailwind-carousel-in-rails-7-3fgg</link>
      <guid>https://dev.to/topofocus/tailwind-carousel-in-rails-7-3fgg</guid>
      <description>&lt;p&gt;After being absence for a while, I recently began to reshape my Rails skills.&lt;/p&gt;

&lt;p&gt;A basic Rails7-setup now includes TailwindCSS and TurboFrames. &lt;br&gt;
I designed a simple Website providing a carousel as eye-catcher. Sure – you can copy the code from &lt;a href="https://tailwind-elements.com/docs/standard/components/carousel/"&gt;Tailwind Elements&lt;/a&gt;, install the &lt;code&gt;tw-elements&lt;/code&gt; javascript-library and anything runs out of the box.&lt;/p&gt;

&lt;p&gt;But that's not very rubyish. Each time you want to change something, you have to touch the source-code.  I like the approach to have a &lt;em&gt;configuration file&lt;/em&gt;, providing input-data for a helper to create the carousel on the fly.&lt;/p&gt;
&lt;h2&gt;
  
  
  What defines a Carousel
&lt;/h2&gt;

&lt;p&gt;As shown in the Cover Photo (which is taken from the &lt;a href="https://tailwind-elements.com/docs/standard/components/carousel/"&gt;Tailwind Elements Page&lt;/a&gt;, we need&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;an image file&lt;/li&gt;
&lt;li&gt;a title&lt;/li&gt;
&lt;li&gt;a short description&lt;/li&gt;
&lt;li&gt;a link to other content&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;
  
  
  Configuration in config/carousel.yml
&lt;/h2&gt;

&lt;p&gt;It seems only natural to put anything in a yaml-config-file. Lets create &lt;code&gt;/config/carousel.yml&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;---
- :first:
    :link:  first
    :image: dizzy-analyst.png 
    :title: Our amazing Approach
    :text:  Explore our unique Solution for all your Problems.
- :second:
    :link:  option
    :image: dizzy-woman.png 
    :title: Feedback
    :text:  We encourage you to provide critical feedback.

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The image-files have to be copied into &lt;code&gt;/app/assets/images&lt;/code&gt;! Its assumed, that the links just point to anchors on the same page. &lt;/p&gt;

&lt;h2&gt;
  
  
  The Controller
&lt;/h2&gt;

&lt;p&gt;Assuming, you have setup a &lt;code&gt;User&lt;/code&gt;-Resource and want to place the carousel on the &lt;code&gt;Index&lt;/code&gt;-Page.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="c1"&gt;# app/controller/users_controller.rb&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;UsersController&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="no"&gt;ApplicationController&lt;/span&gt;
&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;...&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
 &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;index&lt;/span&gt;
    &lt;span class="vi"&gt;@users&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;User&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;all&lt;/span&gt;
    &lt;span class="vi"&gt;@carousel&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;  &lt;span class="no"&gt;YAML&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;load_file&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="no"&gt;Rails&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;root&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="s1"&gt;'config/carousel.yml'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Its very simple: We define the &lt;code&gt;@users&lt;/code&gt; the usual way and read the complete yaml-file into &lt;code&gt;@carousel&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Display carousel in the viewfile
&lt;/h2&gt;

&lt;p&gt;The view-file is evenly simple&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="c1"&gt;# app/views/users/index.html.erb&lt;/span&gt;
&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;header&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;some&lt;/span&gt; &lt;span class="n"&gt;stuff&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;the&lt;/span&gt; &lt;span class="n"&gt;header&lt;/span&gt; &lt;span class="n"&gt;section&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/header&amp;gt;
&amp;lt;%= carousel "testCarousel", @carousel %&amp;gt;

....
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The hole code is delegated to the &lt;code&gt;carousel&lt;/code&gt;-helper.&lt;/p&gt;

&lt;h2&gt;
  
  
  The code: Carousel-Helper
&lt;/h2&gt;

&lt;p&gt;Essentially the &lt;a href="https://tailwind-elements.com/docs/standard/components/carousel/"&gt;Tailwind Elements &lt;/a&gt;-code is translated to fit into &lt;em&gt;Rails-content_tag&lt;/em&gt; elements.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="c1"&gt;# /app/helpers/users_helper.rb&lt;/span&gt;

&lt;span class="k"&gt;module&lt;/span&gt; &lt;span class="nn"&gt;UsersHelper&lt;/span&gt;

  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;carusel&lt;/span&gt; &lt;span class="nb"&gt;id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;  &lt;span class="n"&gt;content&lt;/span&gt;
    &lt;span class="n"&gt;slides&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;  &lt;span class="n"&gt;content&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;count&lt;/span&gt;

    &lt;span class="n"&gt;note&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;n&lt;/span&gt;&lt;span class="p"&gt;){&lt;/span&gt; &lt;span class="s2"&gt;"&amp;lt;h2 class=&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;text-4xl&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;&amp;gt;&lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="n"&gt;n&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="ss"&gt;:title&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;&amp;lt;/h2&amp;gt; &amp;lt;p class=&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;text-xl&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;&amp;gt;&lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="n"&gt;n&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="ss"&gt;:text&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;&amp;lt;/p&amp;gt; "&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="n"&gt;content_tag&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="ss"&gt;:div&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;class:  &lt;/span&gt;&lt;span class="sx"&gt;%w( carousel slide carousel-fade carousel-dark  relative )&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:"data-bs-ride"&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s1"&gt;'carousel'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;id: &lt;/span&gt;&lt;span class="nb"&gt;id&lt;/span&gt; &lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
      &lt;span class="n"&gt;content_tag&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="ss"&gt;:div&lt;/span&gt; &lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;class: &lt;/span&gt;&lt;span class="sx"&gt;%w( carousel-indicators absolute right-0 bottom-0 left-0 flex justify-center p-0 mb-4 )&lt;/span&gt; &lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
      &lt;span class="n"&gt;raw&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="o"&gt;..&lt;/span&gt; &lt;span class="n"&gt;slides&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;map&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;count&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;
          &lt;span class="n"&gt;label&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;  &lt;span class="s2"&gt;"Slide &lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="n"&gt;count&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
          &lt;span class="n"&gt;raw&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;  &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;count&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;zero?&lt;/span&gt;
           &lt;span class="n"&gt;content_tag&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="ss"&gt;:button&lt;/span&gt; &lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kp"&gt;nil&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;  &lt;span class="ss"&gt;type: &lt;/span&gt;&lt;span class="s1"&gt;'button'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:"data-bs-target"&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s2"&gt;"#&lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="nb"&gt;id&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:"data-bs-slide-to"&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;count&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:"aria-current"&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s2"&gt;"true"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:"aria-label"&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;label&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;class: &lt;/span&gt;&lt;span class="s2"&gt;"active"&lt;/span&gt; &lt;span class="p"&gt;)&lt;/span&gt;
                &lt;span class="k"&gt;else&lt;/span&gt;
           &lt;span class="n"&gt;content_tag&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="ss"&gt;:button&lt;/span&gt; &lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kp"&gt;nil&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;  &lt;span class="ss"&gt;type: &lt;/span&gt;&lt;span class="s1"&gt;'button'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:"data-bs-target"&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s2"&gt;"#&lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="nb"&gt;id&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:"data-bs-slide-to"&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;count&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:"aria-label"&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;label&lt;/span&gt; &lt;span class="p"&gt;)&lt;/span&gt;
                &lt;span class="k"&gt;end&lt;/span&gt;
             &lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;end&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;join&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="k"&gt;end&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt;
       &lt;span class="n"&gt;content_tag&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="ss"&gt;:div&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;class: &lt;/span&gt;&lt;span class="sx"&gt;%w( carousel-inner relative w-3/2 overflow-hidden )&lt;/span&gt; &lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
        &lt;span class="n"&gt;raw&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="n"&gt;content&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;map&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;with_index&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;index&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;
          &lt;span class="n"&gt;h&lt;/span&gt;  &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;values&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;first&lt;/span&gt;
            &lt;span class="c1"&gt;# first image ist active&lt;/span&gt;
            &lt;span class="n"&gt;class_attributes&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;index&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;zero?&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="sx"&gt;%w( carousel-item active relative float-left w-full )&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sx"&gt;%w( carousel-item relative float-left w-full)&lt;/span&gt;
            &lt;span class="n"&gt;content_tag&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="ss"&gt;:div&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;class: &lt;/span&gt;&lt;span class="n"&gt;class_attributes&lt;/span&gt; &lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
              &lt;span class="n"&gt;content_tag&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="ss"&gt;:a&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;  &lt;span class="ss"&gt;href: &lt;/span&gt;&lt;span class="s2"&gt;"#&lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="n"&gt;h&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="ss"&gt;:link&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; 
              &lt;span class="n"&gt;image_tag&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="n"&gt;h&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="ss"&gt;:image&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;  &lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;class: &lt;/span&gt;&lt;span class="sx"&gt;%w( block w-full)&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt;
              &lt;span class="n"&gt;content_tag&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="ss"&gt;:div&lt;/span&gt; &lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;raw&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;note&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;h&lt;/span&gt;&lt;span class="p"&gt;]),&lt;/span&gt; &lt;span class="ss"&gt;class: &lt;/span&gt;&lt;span class="sx"&gt;%w( carousel-caption hidden sm:block absolute text-center )&lt;/span&gt; &lt;span class="p"&gt;)&lt;/span&gt;
              &lt;span class="k"&gt;end&lt;/span&gt;
            &lt;span class="k"&gt;end&lt;/span&gt;
          &lt;span class="k"&gt;end&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;join&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="k"&gt;end&lt;/span&gt;  &lt;span class="o"&gt;+&lt;/span&gt;
      &lt;span class="n"&gt;content_tag&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="ss"&gt;:button&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;class: &lt;/span&gt;&lt;span class="sx"&gt;%w( carousel-control-prev absolute top-0 bottom-0 flex items-center justify-center p-0 text-center border-0 hover:outline-none hover:no-underline focus:outline-none focus:no-underline left-0 )&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                  &lt;span class="ss"&gt;type: &lt;/span&gt;&lt;span class="s1"&gt;'button'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:"data-bs-target"&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s2"&gt;"#&lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="nb"&gt;id&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:"data-bs-slide"&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s2"&gt;"prev"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
                      &lt;span class="n"&gt;content_tag&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="ss"&gt;:span&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kp"&gt;nil&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;class: &lt;/span&gt;&lt;span class="sx"&gt;%w( carousel-control-prev-icon inline-block bg-no-repeat )&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:"aria-hidden"&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s2"&gt;"true"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt;
                      &lt;span class="n"&gt;content_tag&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="ss"&gt;:span&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"Previous"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;class: &lt;/span&gt;&lt;span class="s2"&gt;"visually-hidden"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
                                                                                            &lt;span class="k"&gt;end&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt;
      &lt;span class="n"&gt;content_tag&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="ss"&gt;:button&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;class: &lt;/span&gt;&lt;span class="sx"&gt;%w(carousel-control-next absolute top-0 bottom-0 flex items-center justify-center p-0 text-center border-0 hover:outline-none hover:no-underline focus:outline-none focus:no-underline right-0)&lt;/span&gt; &lt;span class="p"&gt;,&lt;/span&gt;
                  &lt;span class="ss"&gt;type: &lt;/span&gt;&lt;span class="s1"&gt;'button'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:"data-bs-target"&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s2"&gt;"#&lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="nb"&gt;id&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:"data-bs-slide"&lt;/span&gt;&lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s2"&gt;"next"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
                      &lt;span class="n"&gt;content_tag&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="ss"&gt;:span&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kp"&gt;nil&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;class: &lt;/span&gt;&lt;span class="sx"&gt;%w( carousel-control-next-icon inline-block bg-no-repeat )&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:"aria-hidden"&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s2"&gt;"true"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt;
                      &lt;span class="n"&gt;content_tag&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="ss"&gt;:span&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"Next"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;class: &lt;/span&gt;&lt;span class="s2"&gt;"visually-hidden"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
                                                                                            &lt;span class="k"&gt;end&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;


  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Et voila, the carousel is displayed in &lt;code&gt;localhost:3000/users&lt;/code&gt;. &lt;/p&gt;

&lt;p&gt;Further customization happens in the helper-code (by trained personal). The display-format for &lt;code&gt;title&lt;/code&gt; and  &lt;code&gt;description&lt;/code&gt;, for example, can be changed in the Lambda in row 3. &lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;The goal was, to separate Content and Function. Its just a matter of editing the `config/carousel.yml' file to update the contents of the carousel. &lt;/p&gt;

</description>
    </item>
    <item>
      <title>The Art of Initialising Objects</title>
      <dc:creator>Hartmut B.</dc:creator>
      <pubDate>Tue, 15 Dec 2020 17:22:01 +0000</pubDate>
      <link>https://dev.to/topofocus/the-art-of-initialising-objects-1b69</link>
      <guid>https://dev.to/topofocus/the-art-of-initialising-objects-1b69</guid>
      <description>&lt;p&gt;Last week, I wrote about &lt;a href="https://dev.to/topofocus/composition-in-ruby-2cff"&gt;Composition in Ruby&lt;/a&gt;. A module was used to masquerade the initialization of an Object. &lt;/p&gt;

&lt;p&gt;This post introduces another way to simplify programming.&lt;/p&gt;

&lt;p&gt;Ruby class names, like their java counterparts, tend to be &lt;em&gt;verbose&lt;/em&gt;. They are sometimes easy to remember. Programs -- on the other side -- are sometimes difficult to read. &lt;/p&gt;

&lt;p&gt;In the &lt;a href="https://dev.to/topofocus/composition-in-ruby-2cff"&gt;other Post&lt;/a&gt; a cryptic &lt;em&gt;Class.new&lt;/em&gt; was transformed to a &lt;em&gt;speaking&lt;/em&gt; Object-call:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="c1"&gt;# Previously&lt;/span&gt;
&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="no"&gt;Order&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt; &lt;span class="ss"&gt;kind: price: &lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;ordertype: :lmt&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;total_amount: &lt;/span&gt;&lt;span class="mi"&gt;100&lt;/span&gt;
&lt;span class="c1"&gt;# result&lt;/span&gt;
&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="no"&gt;Limit&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;order&lt;/span&gt; &lt;span class="ss"&gt;price: &lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;size: &lt;/span&gt;&lt;span class="mi"&gt;100&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;However, this approach requires some overhead.&lt;/p&gt;

&lt;h3&gt;
  
  
  A Remind to Stenography
&lt;/h3&gt;

&lt;p&gt;A long time ago, mostly women had the capability to write as fast as one can talk. They substituted long phrases with something they mysteriously could translate to readable words later. &lt;/p&gt;

&lt;p&gt;The same technique is useful to clarify ruby scripts, too&lt;/p&gt;

&lt;p&gt;A few days ago, I had to write some queries for &lt;a href="https://dev.to/topofocus/activeorient-universal-store-facility-58bi"&gt;ActiveOrient&lt;/a&gt;. The query-generator is located in &lt;code&gt;OrientSupport::OrientQuery&lt;/code&gt;.&lt;br&gt;&lt;br&gt;
For each subquery a new object is created. &lt;/p&gt;

&lt;p&gt;In a script, its obvious that one can choose another constant to substitute the long name. This fails if used elsewhere and is truly bad practice.&lt;/p&gt;
&lt;h3&gt;
  
  
  Lamba's to the rescue
&lt;/h3&gt;

&lt;p&gt;As many modern ruby-classes, &lt;code&gt;OrientSupport::OrientQuery&lt;/code&gt; is initialized with a bunch of hash-items.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;query&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;  &lt;span class="no"&gt;OrientSupport&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;OrientQuery&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;  &lt;span class="ss"&gt;from: &lt;/span&gt;&lt;span class="no"&gt;TheList&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;where: &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="ss"&gt;name: &lt;/span&gt;&lt;span class="s1"&gt;'Maria Hellweg'&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Define a Lamba&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;q&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;**&lt;/span&gt;&lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="p"&gt;){&lt;/span&gt; &lt;span class="no"&gt;OrientSupport&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;OrientQuery&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt; &lt;span class="o"&gt;**&lt;/span&gt;&lt;span class="n"&gt;args&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then the simple query can be rewritten&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;maria&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;q&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt; &lt;span class="ss"&gt;from: &lt;/span&gt;&lt;span class="no"&gt;TheList&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;where: &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="ss"&gt;name: &lt;/span&gt;&lt;span class="s1"&gt;'Maria Hellweg'&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;maria&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;to_s&lt;/span&gt;
 &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s2"&gt;"select from the_list where name = 'Maria Hellweg' "&lt;/span&gt;
&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;maria&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;execute&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;...&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This trick creates a new query-object just by typing &lt;code&gt;q[]&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;This is must helpful to create standard-queries&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;
&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;q&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt; &lt;span class="ss"&gt;projection: &lt;/span&gt;&lt;span class="n"&gt;address&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;from: &lt;/span&gt;&lt;span class="no"&gt;TheList&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;where: &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="ss"&gt;name: &lt;/span&gt;&lt;span class="s1"&gt;'Maria Hellweg'&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nf"&gt;execute&lt;/span&gt;
&lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s2"&gt;"Walddornweg 23"&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;and it can be nested&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;  &lt;span class="n"&gt;q&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt; &lt;span class="ss"&gt;from: &lt;/span&gt;&lt;span class="n"&gt;q&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt; &lt;span class="ss"&gt;from: &lt;/span&gt;&lt;span class="no"&gt;TestQuery&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;where&lt;/span&gt;&lt;span class="p"&gt;:{&lt;/span&gt; &lt;span class="ss"&gt;a: &lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt; &lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;c: &lt;/span&gt;&lt;span class="s1"&gt;'ufz'&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="ss"&gt;kind: &lt;/span&gt;&lt;span class="s1"&gt;'traverse'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;projection: :day&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;to_s&lt;/span&gt;
 &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s2"&gt;"traverse day from ( select from test_query where a = 2 and c = 'ufz' ) "&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Conclusion
&lt;/h3&gt;

&lt;p&gt;Commonly lamba's are used to introduce aspects of functional programming to ruby scripts. However, they can create objects as well.&lt;br&gt;
This trick avoids assignments of simple constants to complicated class names.  Its a strictly local solution with minimal overhead and without any side effects. &lt;/p&gt;

</description>
      <category>ruby</category>
      <category>objects</category>
      <category>oop</category>
    </item>
    <item>
      <title>Composition in Ruby</title>
      <dc:creator>Hartmut B.</dc:creator>
      <pubDate>Fri, 11 Dec 2020 10:57:35 +0000</pubDate>
      <link>https://dev.to/topofocus/composition-in-ruby-2cff</link>
      <guid>https://dev.to/topofocus/composition-in-ruby-2cff</guid>
      <description>&lt;p&gt;As Rubyists prepare for the most anticipated release of Ruby 3.0, its worth looking to unchanged principles. &lt;/p&gt;

&lt;h2&gt;
  
  
  Composition
&lt;/h2&gt;

&lt;p&gt;One exiting feature of the ruby language is the presence of &lt;code&gt;Modules&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="k"&gt;module&lt;/span&gt; &lt;span class="nn"&gt;LimitOrder&lt;/span&gt;
  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;price&lt;/span&gt;
    &lt;span class="vi"&gt;@price&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Order&lt;/span&gt; 
   &lt;span class="kp"&gt;attr&lt;/span&gt; &lt;span class="ss"&gt;:what&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:amount&lt;/span&gt;
  &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;...&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;StockOrder&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="no"&gt;Order&lt;/span&gt;
  &lt;span class="kp"&gt;include&lt;/span&gt; &lt;span class="no"&gt;LimitOrder&lt;/span&gt;
  &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;...&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;StockOrder&lt;/code&gt; inheritances anything from &lt;code&gt;Order&lt;/code&gt; and has access to properties and methods of &lt;code&gt;LimitOrder&lt;/code&gt;.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;include&lt;/code&gt; works on instances of an object. Thus, any object generated by &lt;code&gt;Stockorder.new&lt;/code&gt; can access the &lt;code&gt;price&lt;/code&gt; method.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;extend&lt;/code&gt; on the other hand &lt;em&gt;includes&lt;/em&gt; properties and methods  to classes and modules.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Instantiate Objects without publicly calling &lt;code&gt;new&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;Let's design a module &lt;code&gt;OrderPrototype&lt;/code&gt;. Its main purpose is to provide a method &lt;code&gt;order&lt;/code&gt;, which finally calls &lt;code&gt;Order.new&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="k"&gt;module&lt;/span&gt; &lt;span class="nn"&gt;OrderPrototype&lt;/span&gt;
  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;defaults&lt;/span&gt;
   &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;order&lt;/span&gt;  &lt;span class="o"&gt;**&lt;/span&gt;&lt;span class="n"&gt;fields&lt;/span&gt;
    &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;...&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;   &lt;span class="c1"&gt;## process fields and fillup arguments&lt;/span&gt;
    &lt;span class="no"&gt;Order&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt; &lt;span class="o"&gt;**&lt;/span&gt;&lt;span class="n"&gt;arguments&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The composition process starts by defining a module &lt;code&gt;Limit&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="k"&gt;module&lt;/span&gt; &lt;span class="nn"&gt;Limit&lt;/span&gt;
 &lt;span class="kp"&gt;extend&lt;/span&gt; &lt;span class="no"&gt;OrderPrototype&lt;/span&gt;

 &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="nb"&gt;self&lt;/span&gt;
   &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;defaults&lt;/span&gt;
     &lt;span class="k"&gt;super&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;merge&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="ss"&gt;order_type: :limit&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;  &lt;span class="ss"&gt;tif: :good_till_cancelled&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
   &lt;span class="k"&gt;end&lt;/span&gt;
 &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;class &amp;lt;&amp;lt; self&lt;/code&gt; assigns the following methods to the class-level.  &lt;code&gt;defaults&lt;/code&gt; are processed by &lt;code&gt;OrderProtoype.order&lt;/code&gt;. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;code&gt;Limit.order size: 1, (...)&lt;/code&gt; instantiates a specialized &lt;code&gt;Order&lt;/code&gt;-Object without inheritance.&lt;/strong&gt; Other useful order prototypes are &lt;code&gt;Market.order&lt;/code&gt;, &lt;code&gt;StopLimit.order&lt;/code&gt; a.s.o. &lt;/p&gt;

&lt;p&gt;The &lt;code&gt;Limit&lt;/code&gt;-object acts as a singleton&lt;br&gt;
masquerading as constructor for conventional ruby objects. &lt;/p&gt;

&lt;p&gt;The approach is implemented in: &lt;a href="https://github.com/ib-ruby/ib-extensions/blob/master/lib/ib/order-prototypes.rb"&gt;https://github.com/ib-ruby/ib-extensions/blob/master/lib/ib/order-prototypes.rb&lt;/a&gt;&lt;br&gt;
and further &lt;a href="https://ib-ruby.github.io/ib-doc/order_prototypes.html"&gt;documented here&lt;/a&gt;&lt;/p&gt;

</description>
      <category>ruby</category>
      <category>modules</category>
      <category>composition</category>
      <category>singleton</category>
    </item>
    <item>
      <title>ActiveOrient: Universal Store Facility</title>
      <dc:creator>Hartmut B.</dc:creator>
      <pubDate>Sat, 03 Aug 2019 19:54:16 +0000</pubDate>
      <link>https://dev.to/topofocus/activeorient-universal-store-facility-58bi</link>
      <guid>https://dev.to/topofocus/activeorient-universal-store-facility-58bi</guid>
      <description>&lt;p&gt;In &lt;a href="https://dev.to/topofocus/activeorient-inheritance-edges-and-nodes-3d4f"&gt;Part 3&lt;/a&gt; we claimed »Inheritance and the flexibility of the graphical vertex &amp;amp; edge approach open sudden opportunities.« Let's prove it right away. &lt;/p&gt;

&lt;h2&gt;
  
  
  The power of RID
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;OrientDB&lt;/code&gt; is a »multi model database«, capable to act as a (SQL)RDMS-, a KeyStore- and a Graph-Database. The KeyStore-Design requires the presence of an universal Key, that's &lt;code&gt;RID&lt;/code&gt;. &lt;/p&gt;

&lt;p&gt;Each record has a &lt;code&gt;RID&lt;/code&gt;, each Object is fully identified through its &lt;code&gt;RID&lt;/code&gt;. Simple, but powerfull.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="no"&gt;Person&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;last&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;rid&lt;/span&gt;   &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s2"&gt;"34:0"&lt;/span&gt;
&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="s2"&gt;"#34:0"&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;expand&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;to_human&lt;/span&gt; 
 &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s2"&gt;"&amp;lt;Person[34:0] (...) &amp;gt;"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Data-items loaded from the database carry their class-id. &lt;code&gt;ActiveOrient&lt;/code&gt; autoloads the object and assigns the corresponding ruby-class. Thus any method defined in the model is accessible, any attribute is present as well as any join and any connected edge is waiting to be discovered. &lt;/p&gt;

&lt;h2&gt;
  
  
  Time Grid
&lt;/h2&gt;

&lt;p&gt;Think of a mesh of date-items, supporting  one central goal: Provide an even access-time to any Date of a given time-period, to any item connected to the grid. &lt;/p&gt;

&lt;p&gt;This Graph is realized&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Jahr -- [MONTH_OF] -- Monat --[DAY_OF]-- Tag --[TIME_OF]-- Stunde&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The nodes are crosslinked via GRID_OF-edges and any point of the grid is easily accessed.&lt;/p&gt;

&lt;p&gt;To use the time-grid, install the &lt;a href="https://github.com/topofocus/orientdb_time_graph"&gt;OrientDB-Time-Graph-Gem&lt;/a&gt;. It creates the grid and defines a method &lt;code&gt;to_tg&lt;/code&gt; for &lt;code&gt;String&lt;/code&gt; and &lt;code&gt;Date/Time&lt;/code&gt;,&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="no"&gt;Date&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;today&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;to_tg&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;datum&lt;/span&gt;
 &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="no"&gt;Fri&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mo"&gt;02&lt;/span&gt; &lt;span class="no"&gt;Aug&lt;/span&gt; &lt;span class="mi"&gt;2019&lt;/span&gt; 
 &lt;span class="c1"&gt;#  and &lt;/span&gt;
&lt;span class="s2"&gt;"4.6.2015"&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;to_tg&lt;/span&gt;
 &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="c1"&gt;#&amp;lt;TG::Tag:0x00000000043c8c60 (...)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Store Items
&lt;/h4&gt;

&lt;p&gt;By simply &lt;code&gt;assigning&lt;/code&gt; a database-record to the &lt;code&gt;Tag&lt;/code&gt;-Object, the universal store facility is created. &lt;/p&gt;

&lt;p&gt;Lets go back to our family of &lt;a href="https://dev.to/topofocus/activeorient-inheritance-edges-and-nodes-3d4f"&gt;Part 3&lt;/a&gt; and assign &lt;code&gt;Seema's&lt;/code&gt; birthday.  We use a specialized edge-class &lt;code&gt;HAS_BIRTHDAY&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="no"&gt;E&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;create_class&lt;/span&gt; &lt;span class="ss"&gt;:has_birthday&lt;/span&gt;
&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;sema&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;Child&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;where&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="ss"&gt;name: &lt;/span&gt;&lt;span class="s1"&gt;'Seema'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;first&lt;/span&gt;
&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="s2"&gt;"20.6.2010"&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;to_tg&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;assign&lt;/span&gt; &lt;span class="ss"&gt;vertex: &lt;/span&gt;&lt;span class="n"&gt;sema&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;via: &lt;/span&gt;&lt;span class="no"&gt;HAS_BIRTHDAY&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Query
&lt;/h4&gt;

&lt;p&gt;Let's consider two use-cases&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;we just want to know Seemas birthday&lt;/li&gt;
&lt;li&gt;we are interested in all birthdays in June 2010&lt;/li&gt;
&lt;/ul&gt;

&lt;h5&gt;
  
  
  Seemas Birthday
&lt;/h5&gt;

&lt;p&gt;We can simply get the Child-Record and follow the link to the time-grid.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;sema&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;Child&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;where&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="ss"&gt;name: &lt;/span&gt;&lt;span class="s1"&gt;'Seema'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;first&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;to_human&lt;/span&gt;
&lt;span class="s2"&gt;"&amp;lt;Child[147:0]: in: {IS_CHILD=&amp;gt;1, HAS_BIRTHDAY=&amp;gt;1}, name : Seema&amp;gt;"&lt;/span&gt; 

&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;seema&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;nodes&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:in&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;via: &lt;/span&gt;&lt;span class="sr"&gt;/birth/&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;datum&lt;/span&gt;  &lt;span class="c1"&gt;# firing a query &lt;/span&gt;
 &lt;span class="c1"&gt;#or&lt;/span&gt;
&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;seema&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;in_has_birthday&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;out&lt;/span&gt;                &lt;span class="c1"&gt;# performs action in ruby&lt;/span&gt;
 &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="no"&gt;Sun&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;20&lt;/span&gt; &lt;span class="no"&gt;Jun&lt;/span&gt; &lt;span class="mi"&gt;2010&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is similar to an RDMS(SQL)-approach.&lt;/p&gt;

&lt;h5&gt;
  
  
  Any Birthday in a given range
&lt;/h5&gt;

&lt;p&gt;Suppose, you got a huge database, full of birthdays and want to mine the data. In the RDMS-World you would query the hole database-table. The more data, to longer it takes. Even if you are just interested in People with Birthdays in the same month then Seema, there is no way to avoid accessing all birthday-records in store. &lt;/p&gt;

&lt;p&gt;The »Time-Graph« offers constant access time regardless of the size.&lt;br&gt;
We just jump to one boundary of our range of interest and traverse the next 30 day-records.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;start&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"1.6.2010"&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;to_tg&lt;/span&gt;   
&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;start&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;vector&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="mi"&gt;30&lt;/span&gt; &lt;span class="p"&gt;){&lt;/span&gt; &lt;span class="ss"&gt;:out_has_birthday&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="c1"&gt;# INFO-&amp;gt;select out_has_birthday from  ( traverse  outE('tg_grid_of').in  from #55:5042 while $depth &amp;lt; 30   )  where $depth &amp;gt;= 0 &lt;/span&gt;
 &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"#52:5043"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; 
&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;start&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;vector&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="mi"&gt;30&lt;/span&gt; &lt;span class="p"&gt;){&lt;/span&gt; &lt;span class="ss"&gt;:out_has_birthday&lt;/span&gt; &lt;span class="p"&gt;}.&lt;/span&gt;&lt;span class="nf"&gt;expand&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;nodes&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;via: &lt;/span&gt;&lt;span class="sr"&gt;/birth/&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;to_human&lt;/span&gt;
&lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;[[&lt;/span&gt;&lt;span class="s2"&gt;"&amp;lt;TgChild[147:0]: in: {TG_IS_CHILD=&amp;gt;1, TG_HAS_BIRTHDAY=&amp;gt;1}, name : Seema&amp;gt;"&lt;/span&gt;&lt;span class="p"&gt;]]&lt;/span&gt; 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The method »vector« encapsulates the traverse query. We follow 30 time-grid-links (30 days) and are looking for an property »out_has_birthday«. The query returns an array of &lt;code&gt;RID&lt;/code&gt;'s  (of Time-Grid-Elements). We expand them manually and follow the link &lt;code&gt;HAS_BIRTHDAY&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;If we are interested in the count of birthday's in a specific range:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;start&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;vector&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="mi"&gt;30&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;function: :count&lt;/span&gt; &lt;span class="p"&gt;){&lt;/span&gt; &lt;span class="ss"&gt;:out_has_birthday&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; 
 &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Conclusion
&lt;/h3&gt;

&lt;p&gt;Database Design matters, even if a flexible multi-model-database is used. This simple pattern opens a door to »sustainable programming«. In contrast to classical RDMS(SQK)-Databases, using a Time-Grid, time-dependent data are stored in an unified environment. Queries are time-invariant. That means: if a database matures, grows and evolves, on can expect constant access times to its heart: the Time-Grid. The possibility of an assignment of any (seriable) ruby object to the time-grid is self evident. &lt;/p&gt;

</description>
      <category>ruby</category>
      <category>activeorient</category>
      <category>orientdb</category>
      <category>timegrid</category>
    </item>
    <item>
      <title>ActiveOrient: Inheritance, Edges and Nodes</title>
      <dc:creator>Hartmut B.</dc:creator>
      <pubDate>Wed, 31 Jul 2019 11:50:04 +0000</pubDate>
      <link>https://dev.to/topofocus/activeorient-inheritance-edges-and-nodes-3d4f</link>
      <guid>https://dev.to/topofocus/activeorient-inheritance-edges-and-nodes-3d4f</guid>
      <description>&lt;p&gt;This is Part 3 of the ActiveOrient Series.&lt;/p&gt;

&lt;p&gt;In &lt;a href="https://dev.to/topofocus/activeorient-joins-and-links-j2d"&gt;Part 2&lt;/a&gt; we investigated similarities between RDMS(ActiveRecord)-Joins and unidirectional links and joins in &lt;code&gt;ActiveOrient&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Our example Database consisting of Persons, wo are either father, child or (implicitly) parent enabled queries like &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Which are the grandchilds of a father 
(&lt;code&gt;Person.grandchilds( of: 'Reimund' )&lt;/code&gt; remember?&lt;/li&gt;
&lt;li&gt;Who is a father? &lt;/li&gt;
&lt;li&gt;Who does not have children.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For now, we stick by our &lt;code&gt;Person&lt;/code&gt; class, but organize the data with directional links and introduce inheritance.&lt;/p&gt;

&lt;h2&gt;
  
  
  Inheritance
&lt;/h2&gt;

&lt;p&gt;In the self-referential approach, a child is a child, because there is a link in the &lt;code&gt;children&lt;/code&gt;-property of &lt;code&gt;Person&lt;/code&gt;. If we have to decide, if some action is allowed for the Person, we have to query the database and look for those entries. Thats inefficient.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="no"&gt;Person&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;create_class&lt;/span&gt; &lt;span class="ss"&gt;:child&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:father&lt;/span&gt;
  &lt;span class="c1"&gt;# INFO-&amp;gt;CREATE CLASS child EXTENDS person&lt;/span&gt;
  &lt;span class="c1"&gt;# INFO-&amp;gt;CREATE CLASS father EXTENDS person&lt;/span&gt;
 &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="no"&gt;Child&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="no"&gt;Father&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;creates inherit classes. A &lt;code&gt;Child&lt;/code&gt;, its a specialized &lt;code&gt;Person&lt;/code&gt;. In the model-file (&lt;code&gt;/model/child.rb&lt;/code&gt;) we can express this be defining customized methods. As expected, children and fathers are persons:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'Andrea'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="s1"&gt;'Susi'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="s1"&gt;'Seema'&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nf"&gt;map&lt;/span&gt;  &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="no"&gt;Child&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;create&lt;/span&gt; &lt;span class="ss"&gt;name: &lt;/span&gt;&lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
 &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"Otto"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="s2"&gt;"Joseph"&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nf"&gt;map&lt;/span&gt;  &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="no"&gt;Father&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;create&lt;/span&gt; &lt;span class="ss"&gt;name: &lt;/span&gt;&lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
 &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="no"&gt;Person&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;count&lt;/span&gt;     &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;
 &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="no"&gt;Father&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;count&lt;/span&gt;     &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Instead of querying the database for occurrences of a reference to a person record in &lt;code&gt;Person.children&lt;/code&gt;, we just ask for the Class and know, this is a child. To list all children, we don't have to query all persons, we just express &lt;code&gt;Child.query.order(name: :asc).execute&lt;/code&gt;. Much better. &lt;/p&gt;

&lt;p&gt;The implementation does not require changes to our database-schema. Anything works with self-referential links, as before. And it is still static. So let change this.&lt;/p&gt;

&lt;h2&gt;
  
  
  Edges and Nodes
&lt;/h2&gt;

&lt;p&gt;The most common feature of a &lt;em&gt;Graph-Database&lt;/em&gt; is the presence of Vertices and Edges. Our present approach uses only Vertices. &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Edges connect Vertices bidirectional. &lt;/li&gt;
&lt;li&gt;Any Vertex has special properties: &lt;code&gt;in&lt;/code&gt; and &lt;code&gt;out&lt;/code&gt; which are arrays of links to Edges.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;ActiveOrient&lt;/code&gt; provides a method &lt;code&gt;nodes&lt;/code&gt;. It follows the attached edge and lists any Vertex present »on the other side of the Edge«. &lt;/li&gt;
&lt;li&gt; Vertices are connected through the method &lt;code&gt;:assign&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Assuming, we want to represent the relationships of persons, created above,&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="no"&gt;E&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;create_class&lt;/span&gt; &lt;span class="ss"&gt;:is_family&lt;/span&gt;
 &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="no"&gt;IS_FAMILY&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;create_class&lt;/span&gt; &lt;span class="ss"&gt;:is_child&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:is_father&lt;/span&gt;
 &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;hugo&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;  &lt;span class="no"&gt;Person&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;create&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="ss"&gt;name: &lt;/span&gt;&lt;span class="s1"&gt;'Hugo'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
 &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;hugo&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;assign&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="ss"&gt;via: &lt;/span&gt;&lt;span class="no"&gt;IS_CHILD&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;vertex: &lt;/span&gt;&lt;span class="no"&gt;Child&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;like&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="s1"&gt;'name = S*'&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
 &lt;span class="c1"&gt;# INFO-&amp;gt;select from child where name.left(1) = 'S' order by name asc&lt;/span&gt;
 &lt;span class="c1"&gt;# INFO-&amp;gt;CREATE EDGE is_child from #29:6 to [#54:0, #53:0] &lt;/span&gt;
 &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;hugo&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;assign&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="ss"&gt;via: &lt;/span&gt;&lt;span class="no"&gt;IS_FATHER&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;vertex: &lt;/span&gt;&lt;span class="no"&gt;Father&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;where&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="ss"&gt;name: &lt;/span&gt;&lt;span class="s1"&gt;'Otto'&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
 &lt;span class="c1"&gt;# INFO-&amp;gt;CREATE EDGE is_father from #29:6 to [#59:0]&lt;/span&gt;
 &lt;span class="c1"&gt;# then&lt;/span&gt;
 &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;hugo&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;reload!&lt;/span&gt;
 &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;hugo&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;nodes&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="ss"&gt;:out&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;via: &lt;/span&gt;&lt;span class="sr"&gt;/is/&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;count&lt;/span&gt;  &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;
 &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;hugo&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;nodes&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="ss"&gt;:out&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;via: &lt;/span&gt;&lt;span class="no"&gt;IS_FATHER&lt;/span&gt; &lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;first&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;name&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s1"&gt;'otto'&lt;/span&gt;
 &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="no"&gt;Child&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;where&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="ss"&gt;name: &lt;/span&gt;&lt;span class="s1"&gt;'Seema'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;first&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;nodes&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="ss"&gt;:in&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;to_human&lt;/span&gt; 
 &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"&amp;lt;Person[29:6]: out: {IS_FATHER=&amp;gt;1, IS_CHILD=&amp;gt;2}, name : Hugo&amp;gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; 

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--NjOY7oW8--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://thepracticaldev.s3.amazonaws.com/i/ktuv7lsieqbzdo1l9lg4.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--NjOY7oW8--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://thepracticaldev.s3.amazonaws.com/i/ktuv7lsieqbzdo1l9lg4.png" alt="" width="620" height="302"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;First, we create inherent Edges: IS_Family, IS_CHILD and IS_FATHER.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Note&lt;/em&gt;: In &lt;code&gt;ActiveOrient&lt;/code&gt; Edge-Classes are UPERCASE. The database-classes are still lowercase. &lt;/p&gt;

&lt;p&gt;»hugo«, a person, is created. The new record is then assigned through IS_CHILD-Edges to any child-record meeting the search criteria. We managed to connect Susi and Seema. This is followed by an assignment of Otto via IS_FATHER.  &lt;/p&gt;

&lt;p&gt;At last, we queried the relationships. The method &lt;code&gt;:nodes&lt;/code&gt; distinguishes between &lt;code&gt;:in-&lt;/code&gt;going and  &lt;code&gt;:out&lt;/code&gt;-going edges. The assignment occurs on the &lt;code&gt;:out&lt;/code&gt; side of »hugo«. The &lt;code&gt;:via&lt;/code&gt;-parameter filters the edges, either by providing the EDGE_CLASS or an regular expression, which fits the lowercase database class names.&lt;br&gt;
Nodes work in both directions. That's demonstrated in the last query. We start with a Child and ask any relationship. There is only one, to the father-vertex. &lt;/p&gt;

&lt;p&gt;Perhaps you get the idea: This is not the end. Its very simple, to investigate the relationships of the father, for instance, to display the grandparents, their children and so on.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;Inheritance and the flexibility of the graphical vertex &amp;amp; edge approach open sudden opportunities. &lt;code&gt;ActiveOrient&lt;/code&gt; provides some methods to ease the transformation for people (like the author) who thought »relational« their hole life.&lt;/p&gt;

&lt;p&gt;This opens many opportunities. As in real life: Its often more comfortable, to live in a well grounded environment with simple rules then to be responsible for a decent path. With ActiveOrient (and OrientDB) the developer can choose, to work with relations or graphs and s/he can benefit from proven layouts from both worlds. &lt;/p&gt;

&lt;p&gt;In the next part, we will develop a time-graph, able to efficiently organize any time-based data, events, time-series and more.  &lt;/p&gt;

</description>
      <category>ruby</category>
      <category>activeorient</category>
      <category>orientdb</category>
      <category>graphdb</category>
    </item>
    <item>
      <title>ActiveOrient: Joins and Links</title>
      <dc:creator>Hartmut B.</dc:creator>
      <pubDate>Mon, 29 Jul 2019 18:54:52 +0000</pubDate>
      <link>https://dev.to/topofocus/activeorient-joins-and-links-j2d</link>
      <guid>https://dev.to/topofocus/activeorient-joins-and-links-j2d</guid>
      <description>&lt;p&gt;In the &lt;a href="https://dev.to/topofocus/active-orient-introduction-overview-4knj"&gt;Introduction&lt;/a&gt; we created a self-referencing join.&lt;br&gt;
Lets compare with &lt;code&gt;ActiveRecord&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="c1"&gt;# (ActiveRecord) in file /model/person.rb&lt;/span&gt;
&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Person&lt;/span&gt;
  &lt;span class="n"&gt;has_many&lt;/span&gt; &lt;span class="ss"&gt;:children&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;class_name: &lt;/span&gt;&lt;span class="s1"&gt;'Person'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;foreign_key: &lt;/span&gt;&lt;span class="s1"&gt;'father_id'&lt;/span&gt;
  &lt;span class="n"&gt;belongs_to&lt;/span&gt; &lt;span class="ss"&gt;:father&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:class_name&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s1"&gt;'Person'&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="c1"&gt;# then &lt;/span&gt;
 &lt;span class="no"&gt;Person&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;find&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="ss"&gt;name: &lt;/span&gt;&lt;span class="s1"&gt;'Hugo'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;first&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;father&lt;/span&gt; 
 &lt;span class="no"&gt;Person&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;find&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="ss"&gt;name: &lt;/span&gt;&lt;span class="s1"&gt;'Hugo'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;first&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;children&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We omited the tricky part of setting up a database-definition, defining proper indices and perform a migration through rake-tasks and note, that data have to be inserted, too.&lt;/p&gt;

&lt;h2&gt;
  
  
  Insert Data
&lt;/h2&gt;

&lt;p&gt;With ActiveOrient, we just create the database-table, insert our data and are done.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="no"&gt;V&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;create_class&lt;/span&gt; &lt;span class="ss"&gt;:person&lt;/span&gt;
&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;hugo&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;Person&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;create&lt;/span&gt; &lt;span class="ss"&gt;name: &lt;/span&gt;&lt;span class="s1"&gt;'Hugo'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
                       &lt;span class="ss"&gt;father: &lt;/span&gt;&lt;span class="no"&gt;Person&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;create&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="ss"&gt;name: &lt;/span&gt;&lt;span class="s2"&gt;"Reimund"&lt;/span&gt; &lt;span class="p"&gt;),&lt;/span&gt;
                       &lt;span class="ss"&gt;children: &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"Eva"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"Ulli"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"Uwe"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"George"&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nf"&gt;map&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="no"&gt;Person&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;create&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="ss"&gt;name: &lt;/span&gt;&lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s2"&gt;"&amp;lt;Person[150:0]: children: [#146:0, 147:0, #148:0, #149:0], father : &amp;lt;Person[145:0]: name: Reimund&amp;gt;, name: Hugo&amp;gt;"&lt;/span&gt; 

&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;hugo&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;father&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;name&lt;/span&gt;   &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s2"&gt;"Reimund"&lt;/span&gt;
&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;hugo&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;children&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;name&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"Eva"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"Ulli"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"Uwe"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"George"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Note that &lt;code&gt;children&lt;/code&gt; are represented by their database-id's only, this is equal to the foreign_key used by &lt;code&gt;ActiveRecord&lt;/code&gt;. &lt;/p&gt;

&lt;p&gt;The schemaless approach reveals a quick solution and exposes the basic functionality of a comparable RDMS-Database. But there are limits. The possibility to work schemaless does not mean, that ad-hoc designs are favorable. It is, for instance, not possible, to query linked records, unless a proper schema is defined. We are still in the database-world, the world of structured data.&lt;/p&gt;

&lt;h2&gt;
  
  
  Define Properties
&lt;/h2&gt;

&lt;p&gt;It is a good practice, to put an index on any property, which is subject of a query. We want to create a &lt;code&gt;notunique&lt;/code&gt;-Index on the &lt;code&gt;:name&lt;/code&gt; property. &lt;code&gt;:children&lt;/code&gt; are just a &lt;code&gt;list of links&lt;/code&gt;, containing &lt;code&gt;Person&lt;/code&gt; objects and&lt;br&gt;
the &lt;code&gt;:father&lt;/code&gt; is a &lt;code&gt;link&lt;/code&gt;to a &lt;code&gt;Person&lt;/code&gt;-record.  But first, lets delete anything.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="no"&gt;Person&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;delete&lt;/span&gt; &lt;span class="ss"&gt;all: &lt;/span&gt;&lt;span class="kp"&gt;true&lt;/span&gt;
&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="no"&gt;Person&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;create_property&lt;/span&gt;  &lt;span class="ss"&gt;:name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;type: :string&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;index: :notunique&lt;/span&gt;
&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="no"&gt;Person&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;create_property&lt;/span&gt;  &lt;span class="ss"&gt;:children&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;type: :link_list&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:linked_class&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="no"&gt;Person&lt;/span&gt;
&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="no"&gt;Person&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;create_property&lt;/span&gt;  &lt;span class="ss"&gt;:father&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;type: :link&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;linked_class: &lt;/span&gt;&lt;span class="no"&gt;Person&lt;/span&gt;
&lt;span class="c1"&gt;# check&lt;/span&gt;
&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="no"&gt;Person&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;print_properties&lt;/span&gt;
  &lt;span class="no"&gt;Detected&lt;/span&gt; &lt;span class="no"&gt;Properties&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="n"&gt;person&lt;/span&gt;
    &lt;span class="n"&gt;person&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;children&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="no"&gt;LINKLIST&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;person&lt;/span&gt;
    &lt;span class="n"&gt;person&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;father&lt;/span&gt;   &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="no"&gt;LINK&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;person&lt;/span&gt;
    &lt;span class="n"&gt;person&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;name&lt;/span&gt;     &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="no"&gt;STRING&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To insert another record, we must avoid to create a duplicate of the &lt;code&gt;Reimund&lt;/code&gt;-Person.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="n"&gt;pete&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;Person&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;create&lt;/span&gt; &lt;span class="ss"&gt;name: &lt;/span&gt;&lt;span class="s1"&gt;'Pete'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
                     &lt;span class="ss"&gt;father: &lt;/span&gt;&lt;span class="no"&gt;Person&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;upsert&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="ss"&gt;where: &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="ss"&gt;name: &lt;/span&gt;&lt;span class="s2"&gt;"Reimund"&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="p"&gt;),&lt;/span&gt;
                     &lt;span class="ss"&gt;children: &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"Eva"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"Mathew"&lt;/span&gt; &lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nf"&gt;map&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="no"&gt;Person&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;create&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="ss"&gt;name: &lt;/span&gt;&lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Instead of creating a new record for the father, we search the database and use the existing entry. &lt;code&gt;Upsert&lt;/code&gt; inserts a record if no entry is found. That guarantees that &lt;code&gt;:father&lt;/code&gt; is always a valid link.&lt;/p&gt;

&lt;h2&gt;
  
  
  Query the Database
&lt;/h2&gt;

&lt;p&gt;Orientdb Database classes and -records are queried with a SQL dialect. &lt;code&gt;ActiveOrient&lt;/code&gt; provides a method &lt;code&gt;query&lt;/code&gt; to build such queries similar to &lt;code&gt;ActiveRecord&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="no"&gt;Person&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;query&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;where&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="s2"&gt;"father is NOT NULL"&lt;/span&gt; &lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;execute&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;name&lt;/span&gt;
 &lt;span class="c1"&gt;#INFO-&amp;gt;select from person where  father is NOT NULL &lt;/span&gt;
 &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"Peter"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"Hugo"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; 
&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="no"&gt;Person&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;query&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;where&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="s1"&gt;'father.name'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s1"&gt;'Reimund'&lt;/span&gt; &lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;projection&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'name'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;execute&lt;/span&gt;
 &lt;span class="c1"&gt;#INFO-&amp;gt;select name from person where father.name = 'Reimund' &lt;/span&gt;
 &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;[{&lt;/span&gt;&lt;span class="ss"&gt;:name&lt;/span&gt;&lt;span class="o"&gt;=&amp;gt;&lt;/span&gt;&lt;span class="s2"&gt;"Pete"&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="ss"&gt;:name&lt;/span&gt;&lt;span class="o"&gt;=&amp;gt;&lt;/span&gt;&lt;span class="s2"&gt;"Anton"&lt;/span&gt;&lt;span class="p"&gt;}]&lt;/span&gt; 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The first query returns two &lt;code&gt;Person&lt;/code&gt;-records. We display only the property &lt;code&gt;:name&lt;/code&gt;. The second query specifies a projection and returns a list of hashes. &lt;/p&gt;

&lt;h4&gt;
  
  
  Model-helper
&lt;/h4&gt;

&lt;p&gt;Complex queries can be stored in the &lt;code&gt;model-file&lt;/code&gt; of the class. Queries are class-methods. Thus, in &lt;code&gt;/model/person.rb&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Person&lt;/span&gt;
  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nc"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;grandchilds&lt;/span&gt; &lt;span class="ss"&gt;of:
    &lt;/span&gt;&lt;span class="n"&gt;query&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;where&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'father.name'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;of&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
         &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;projection&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="ss"&gt;:children&lt;/span&gt; &lt;span class="p"&gt;)&lt;/span&gt;
   &lt;span class="k"&gt;end&lt;/span&gt;
 &lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The class method returns a &lt;code&gt;OrientQuery&lt;/code&gt;. It can further modified, inspected by calling &lt;code&gt;to_s&lt;/code&gt; and finally &lt;code&gt;executed&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="no"&gt;Person&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;grandchilds&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="ss"&gt;of: &lt;/span&gt;&lt;span class="s1"&gt;'Reimund'&lt;/span&gt; &lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;execute&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;to_human&lt;/span&gt;
&lt;span class="c1"&gt;# INFO-&amp;gt;select children from person where father.name = 'Reimund' &lt;/span&gt;
&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"{ children: #29:5#30:5#31:5#32:4 }"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"{ children: #26:5#27:5 }"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="c1"&gt;# or&lt;/span&gt;
&lt;span class="no"&gt;Person&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;grandchilds&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="ss"&gt;of: &lt;/span&gt;&lt;span class="s1"&gt;'Reimund'&lt;/span&gt; &lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;execute&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;y&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;y&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="ss"&gt;:children&lt;/span&gt;&lt;span class="p"&gt;]}.&lt;/span&gt;&lt;span class="nf"&gt;name&lt;/span&gt;
 &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"Eva"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"Ulli"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"Uwe"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"George"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"Eva"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"Mathew"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For pre-prosessing &lt;code&gt;OrientQuery.execute&lt;/code&gt; exposes any returned record to the optional block. Obviously, we are interested in &lt;code&gt;:children&lt;/code&gt;. The query returns links to &lt;code&gt;Person-Objects&lt;/code&gt; which are expanded by &lt;code&gt;ActiveOrient&lt;/code&gt;. Thus &lt;code&gt;.name&lt;/code&gt; simply addresses the &lt;code&gt;name&lt;/code&gt;-attribute of the returned records.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;The database has basic support for joined tables. Anybody familiar with RDMS-(SQL)-Databases should be comfortable with unidirectional links and joins and their ActiveRecord-like querying. We can develop a draft sketch (schemaless) without any configuration. If necessary, constrains, properties, indices and validations are added. The power of &lt;a href="http://orientdb.com/docs/3.0.x/sql/SQL-Projections.html"&gt;nested projections&lt;/a&gt; goes far beyond anything in the RDMS-world. &lt;/p&gt;

&lt;p&gt;&lt;code&gt;ActiveOrient&lt;/code&gt; combines the power and beauty of ruby with SQL for the 21st Century.&lt;/p&gt;

&lt;p&gt;Unidirectional Links and Joins are nice and familiar. In the next part, we extend this approach to bidirectional Links and take a walk into the world of graphs.&lt;/p&gt;

</description>
      <category>ruby</category>
      <category>activeorient</category>
      <category>orientdb</category>
      <category>sql</category>
    </item>
    <item>
      <title>Active Orient – Introduction &amp; Overview</title>
      <dc:creator>Hartmut B.</dc:creator>
      <pubDate>Wed, 24 Jul 2019 10:46:17 +0000</pubDate>
      <link>https://dev.to/topofocus/active-orient-introduction-overview-4knj</link>
      <guid>https://dev.to/topofocus/active-orient-introduction-overview-4knj</guid>
      <description>&lt;p&gt;How about a (fast) &lt;a href="https://orientdb.com"&gt; open source database&lt;/a&gt; usable without any schema, query-able with sql-statements and able to perform sophisticated graph operations? Not to forget: Easily accessible via an intuitive ruby interface. The latter is &lt;code&gt;ActiveOrient&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Prerequisites
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Install the database ( &lt;a href="https://orientdb.com/download-2/"&gt;Download the OpenSource Database&lt;/a&gt;) and assign a Username&lt;/li&gt;
&lt;li&gt;Make sure that ruby 2.6  is installed (via snap or &lt;a href="//https::/rvm.io"&gt;rvm&lt;/a&gt;). Check if &lt;code&gt;bundle&lt;/code&gt; is installed (otherwise &lt;code&gt;gem install bundle&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;Clone the &lt;a href="https://github.com/topofocus/active-orient.git"&gt;ActiveOrient git archive&lt;/a&gt;  and bundle ruby libraries:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;git clone https://github.com/topofocus/active-orient.git
cd active-orient
bundle install; bundle update
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now modify &lt;code&gt;config/connect.yaml&lt;/code&gt;.&lt;br&gt;
Test, development and production databases are created if they don't exist.&lt;/p&gt;

&lt;p&gt;Then change to &lt;code&gt;/bin&lt;/code&gt; and run&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;./active-orient-console -t
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Simple Start
&lt;/h2&gt;

&lt;p&gt;Any database-class is recognized and allocated. Further, any class created in the process is usable immediately. The behavior of any Class can be customized in &lt;code&gt;model&lt;/code&gt;-files, which are included upon the creation of a class. &lt;/p&gt;

&lt;p&gt;The base-classes &lt;code&gt;V&lt;/code&gt;)ertex and &lt;code&gt;E&lt;/code&gt;)dge are always present. Its good practice, to inherent any user-class from the base-classes.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt; &lt;span class="c1"&gt;# create a class&lt;/span&gt;
    &lt;span class="no"&gt;V&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;create_class&lt;/span&gt; &lt;span class="ss"&gt;:m&lt;/span&gt;   &lt;span class="c1"&gt;# V is the base »vertex» class. M is the vertex-class created The corresponding database-class: »m«.&lt;/span&gt;
 &lt;span class="c1"&gt;# INFO-&amp;gt;CREATE CLASS m EXTENDS &lt;/span&gt;

 &lt;span class="c1"&gt;# create a record&lt;/span&gt;
    &lt;span class="no"&gt;M&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;create&lt;/span&gt; &lt;span class="ss"&gt;name: &lt;/span&gt;&lt;span class="s1"&gt;'Hugo'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;age: &lt;/span&gt;&lt;span class="mi"&gt;46&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;interests: &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt; &lt;span class="s1"&gt;'swimming'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'biking'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'reading'&lt;/span&gt; &lt;span class="p"&gt;]&lt;/span&gt;
 &lt;span class="c1"&gt;# INFO-&amp;gt;CREATE VERTEX m CONTENT {"name":"Hugo","age":46,"interests":["swimming","biking","reading"]}&lt;/span&gt;
    &lt;span class="c1"&gt;# query the database&lt;/span&gt;
    &lt;span class="n"&gt;hugo&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;M&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;where&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="ss"&gt;name: &lt;/span&gt;&lt;span class="s1"&gt;'Hugo'&lt;/span&gt; &lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;first&lt;/span&gt;
    &lt;span class="n"&gt;hugo&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;to_human&lt;/span&gt;
    &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt;&lt;span class="s2"&gt;"&amp;lt;M[177:0]: age: 46, interests: [&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;swimming&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;, &lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;biking&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;, &lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;reading&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;], name : Hugo&amp;gt;"&lt;/span&gt; 
    &lt;span class="c1"&gt;# update the dataset&lt;/span&gt;
    &lt;span class="n"&gt;hugo&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;update&lt;/span&gt; &lt;span class="ss"&gt;father: &lt;/span&gt;&lt;span class="no"&gt;M&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;create&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="ss"&gt;name: &lt;/span&gt;&lt;span class="s2"&gt;"Volker"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;age: &lt;/span&gt;&lt;span class="mi"&gt;76&lt;/span&gt; &lt;span class="p"&gt;)&lt;/span&gt;  &lt;span class="c1"&gt;# we create an internal link&lt;/span&gt;
&lt;span class="c1"&gt;# INFO-&amp;gt;CREATE VERTEX m CONTENT {"name":"Volker","age":76}&lt;/span&gt;
&lt;span class="c1"&gt;# INFO-&amp;gt;update #177:0 set father = #178:0&lt;/span&gt;
    &lt;span class="n"&gt;hugo&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;to_human&lt;/span&gt;
    &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s2"&gt;"&amp;lt;M[177:0]: age : 46, father : &amp;lt;M[178:0]: age : 76, name : Volker&amp;gt;, interests : [&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;swimming&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;, &lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;biking&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;, &lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;reading&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;], name : Hugo&amp;gt;"&lt;/span&gt;
    &lt;span class="n"&gt;hugo&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;father&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;name&lt;/span&gt;    
    &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;volker&lt;/span&gt;
    &lt;span class="c1"&gt;# change array elements&lt;/span&gt;
    &lt;span class="n"&gt;hugo&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;interests&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="s2"&gt;"dancing"&lt;/span&gt;  &lt;span class="c1"&gt;# --&amp;gt; [ 'swimming', 'biking', 'reading', 'dancing' ]&lt;/span&gt;
&lt;span class="c1"&gt;#INFO-&amp;gt;update #177:0  set interests = interests || ['dancing'] &lt;/span&gt;

    &lt;span class="no"&gt;M&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;remove&lt;/span&gt; &lt;span class="n"&gt;hugo&lt;/span&gt; 
    &lt;span class="no"&gt;M&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;delete_class&lt;/span&gt;  &lt;span class="c1"&gt;# removes the class from OrientDB and deletes the ruby-object-definition&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In this brief introduction, we created a Vertex-Class »M«. Then we created a document (record) with some properties. We queried the database using a syntax similar to &lt;code&gt;ActiveRecord&lt;/code&gt;. &lt;br&gt;
Then we created a self-refrencing link which we  followed to access  connected information. &lt;/p&gt;

&lt;p&gt;At last  – using the syntax of ruby-arrays – we added an entry to an embedded list. Anything without any configuration in schema-, model-files or whatsoever. &lt;/p&gt;

&lt;p&gt;This ends Part 1 of the ActiveOrient Mini-Series. &lt;br&gt;
The &lt;a href="https://dev.to/topofocus/activeorient-joins-and-links-j2d"&gt;next part&lt;/a&gt; covers unidirectional links and joins, an introduction to sql-queries and their abstraction with Orientquery&lt;/p&gt;

</description>
      <category>ruby</category>
      <category>orientdb</category>
      <category>sql</category>
      <category>graphdb</category>
    </item>
  </channel>
</rss>
