<?xml version="1.0" encoding="utf-8"?><feed xmlns="http://www.w3.org/2005/Atom" ><generator uri="https://jekyllrb.com/" version="4.2.2">Jekyll</generator><link href="https://www.hocnest.com/feed.xml" rel="self" type="application/atom+xml" /><link href="https://www.hocnest.com/" rel="alternate" type="text/html" /><updated>2025-03-17T13:01:34-04:00</updated><id>https://www.hocnest.com/feed.xml</id><title type="html">Full-stack engineering, design, and product strategy | HocNest Product Studio</title><subtitle>HocNest is a leading software consulting and contracting company specializing in full-stack engineering, design, and product strategy. A 100% distributed digital product studio based in South Florida (Fort Lauderdale, Miami, Hollywood, Boca Raton, West Palm Beach).</subtitle><entry><title type="html">Configure Your First Rails Engine</title><link href="https://www.hocnest.com/blog/configure-rails-engine/" rel="alternate" type="text/html" title="Configure Your First Rails Engine" /><published>2020-07-05T12:56:00-04:00</published><updated>2020-07-05T12:56:00-04:00</updated><id>https://www.hocnest.com/blog/configure-rails-engine</id><content type="html" xml:base="https://www.hocnest.com/blog/configure-rails-engine/"><![CDATA[<p>In <a href="/blog/testing-modular-monolith-engines/">part two</a>, we added rspec and factory bot to our rails engine.</p>

<p>For this third part, I’ll demonstrate how to configure a rails engine in a modular monolith application.</p>

<p><strong><a href="https://github.com/amrani/rails_modular_monolith_demo/tree/master/part_3" target="\_blank">Source Code</a></strong></p>

<p><strong>Controllers</strong></p>

<p>I’ll configure my engine to use my host’s application controller. Then our engines share common behavior like <code class="language-plaintext highlighter-rouge">:current_user</code> or <code class="language-plaintext highlighter-rouge">some_useful_method</code>. We do this without compromise and still respect our dependency boundaries.</p>

<p>Let’s add a <code class="language-plaintext highlighter-rouge">connect_by</code> initializer:</p>

<div class="language-ruby highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1"># config/initializers/connect_by.rb</span>

<span class="no">ConnectBy</span><span class="p">.</span><span class="nf">application_controller</span> <span class="o">=</span> <span class="s2">"ApplicationController"</span>
</code></pre></div></div>

<div class="language-ruby highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1"># engines/connect_by/lib/connect_by/engine.rb</span>

<span class="k">module</span> <span class="nn">ConnectBy</span>
  <span class="n">mattr_accessor</span> <span class="ss">:application_controller</span>

  <span class="o">...</span>
<span class="k">end</span>
</code></pre></div></div>

<p>Update the engine’s application controller.</p>

<div class="language-ruby highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1"># engines/connect_by/app/controllers/connect_by/application_controller.rb</span>

<span class="k">module</span> <span class="nn">ConnectBy</span>
  <span class="k">class</span> <span class="nc">ApplicationController</span> <span class="o">&lt;</span> <span class="no">ConnectBy</span><span class="p">.</span><span class="nf">application_controller</span><span class="p">.</span><span class="nf">constantize</span>
</code></pre></div></div>

<p>Add behavior from the host so the engine can use it.</p>

<div class="language-ruby highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1"># app/controllers/application_controller.rb</span>

<span class="k">class</span> <span class="nc">ApplicationController</span> <span class="o">&lt;</span> <span class="no">ActionController</span><span class="o">::</span><span class="no">Base</span>
  <span class="kp">protected</span>
    <span class="k">def</span> <span class="nf">some_useful_method</span>
    <span class="k">end</span>
<span class="k">end</span>
</code></pre></div></div>

<p><code class="language-plaintext highlighter-rouge">some_useful_method</code> is now hooked into connect_by. Although it works, we can do a lot better.</p>

<p>I want it to be completely apparent that connect_by’s application controller is dependent on <code class="language-plaintext highlighter-rouge">some_useful_method</code>. We can accomplish this with a contract.</p>

<p>Raise an error if connect_by’s application controller does not have it defined.</p>

<div class="language-ruby highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1"># engines/connect_by/app/controllers/connect_by/application_controller.rb</span>

<span class="k">module</span> <span class="nn">ConnectBy</span>
  <span class="k">class</span> <span class="nc">ApplicationController</span> <span class="o">&lt;</span> <span class="no">ConnectBy</span><span class="p">.</span><span class="nf">application_controller</span><span class="p">.</span><span class="nf">constantize</span>
    <span class="k">raise</span> <span class="s2">"Must implement some_useful_method"</span> <span class="k">unless</span> <span class="nb">instance_methods</span><span class="p">.</span><span class="nf">include?</span><span class="p">(</span><span class="ss">:some_useful_method</span><span class="p">)</span>
</code></pre></div></div>

<p>Another improvement is how we organize this functionality. Refactor it using a controller concern.</p>

<div class="language-ruby highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1"># app/controllers/concerns/connect_by/controller_behavior.rb</span>

<span class="k">module</span> <span class="nn">ConnectBy</span>
  <span class="k">module</span> <span class="nn">ControllerBehavior</span>
    <span class="kp">protected</span>
      <span class="k">def</span> <span class="nf">some_useful_method</span>
      <span class="k">end</span>
</code></pre></div></div>

<p>Refactor the host application controller to include the concern.</p>

<div class="language-ruby highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1"># app/controllers/application_controller.rb</span>

<span class="k">class</span> <span class="nc">ApplicationController</span> <span class="o">&lt;</span> <span class="no">ActionController</span><span class="o">::</span><span class="no">Base</span>
  <span class="kp">include</span> <span class="no">ConnectBy</span><span class="o">::</span><span class="no">ControllerBehavior</span>
<span class="k">end</span>
</code></pre></div></div>

<p>And then update our contract:</p>

<div class="language-ruby highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1"># engines/connect_by/app/controllers/connect_by/application_controller.rb</span>

<span class="k">module</span> <span class="nn">ConnectBy</span>
  <span class="k">class</span> <span class="nc">ApplicationController</span> <span class="o">&lt;</span> <span class="no">ConnectBy</span><span class="p">.</span><span class="nf">application_controller</span><span class="p">.</span><span class="nf">constantize</span>
    <span class="k">raise</span> <span class="s2">"Must include ConnectBy::ControllerBehavior"</span> <span class="k">unless</span> <span class="nb">self</span> <span class="o">&lt;</span> <span class="no">ConnectBy</span><span class="o">::</span><span class="no">ControllerBehavior</span>

    <span class="k">raise</span> <span class="s2">"Must implement some_useful_method"</span> <span class="k">unless</span> <span class="nb">instance_methods</span><span class="p">.</span><span class="nf">include?</span><span class="p">(</span><span class="ss">:some_useful_method</span><span class="p">)</span>
</code></pre></div></div>

<p>I’ll test to see if it worked by navigating to <code class="language-plaintext highlighter-rouge">/a/users/sign_in</code> in the browser.</p>

<p>Try removing <code class="language-plaintext highlighter-rouge">some_useful_method</code> from the application controller and confirm the raised error.</p>

<p>Contracts are in place to set expectations.</p>

<p>Many programming languages have native support for contracts. For instance, <a href="https://www.eiffel.org/doc/eiffel/ET-_Design_by_Contract_%28tm%29%2C_Assertions_and_Exceptions" target="\_blank">Eiffel</a> has DBC (Design by Contract) built-in. Also, the team at <a href="https://bluebottlecoffee.com/" target="\_blank">Blue Bottle Coffee</a> shared a <a href="https://github.com/bluebottlecoffee/CBRA-Contracts" target="\_blank">repo</a> and created a DSL for contracts in rails.</p>

<h2 id="takeaway">Takeaway</h2>

<p>We configured our engine to use the host’s application controller by adding an initializer and updating our engine. We did so without breaking our dependency tree and keeping our monolith modular.</p>

<p>The <strong><a href="https://github.com/amrani/rails_modular_monolith_demo/tree/master/part_3" target="\_blank">source code</a></strong> for this part is on Github.</p>

<ul>
  <li><a href="/blog/create-user-rails-engine/">Part 1 - Create Your First Rails Engine</a></li>
  <li><a href="/blog/testing-modular-monolith-engines/">Part 2 - Test Your First Rails Engine</a></li>
  <li><a href="/blog/configure-rails-engine/">Part 3 - Configure Your First Rails Engine</a></li>
</ul>

<h2 id="useful-resources">Useful Resources</h2>

<p>I have <a href="/modular-monolith-resources/">compiled a list</a> of useful resources for rails engines and the modular monolith architecture.</p>

<h1 id="scale-with-rails-engines">Scale With Rails Engines</h1>

<p>Need help scaling your rails application with a modular monolith? <a href="/contact">Talk to us</a></p>]]></content><author><name>David Amrani</name></author><category term="rails" /><category term="architecture" /><category term="engines" /><category term="devise" /><category term="authentication" /><category term="rmm" /><summary type="html"><![CDATA[Learn how to configure your first ruby on rails engine. Part three of three highlights how to configure a rails engine while respecting our modular monolith's dependency boundaries.]]></summary><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://www.hocnest.com/img/puzzle.png" /><media:content medium="image" url="https://www.hocnest.com/img/puzzle.png" xmlns:media="http://search.yahoo.com/mrss/" /></entry><entry><title type="html">Test Your First Rails Engine</title><link href="https://www.hocnest.com/blog/testing-modular-monolith-engines/" rel="alternate" type="text/html" title="Test Your First Rails Engine" /><published>2020-07-04T15:21:00-04:00</published><updated>2020-07-04T15:21:00-04:00</updated><id>https://www.hocnest.com/blog/testing-modular-monolith-engines</id><content type="html" xml:base="https://www.hocnest.com/blog/testing-modular-monolith-engines/"><![CDATA[<p>In <a href="/blog/create-user-rails-engine/">part one</a>, we created a rails 6 engine for our users. Part two will focus on testing. <a href="https://github.com/amrani/rails_modular_monolith_demo/tree/master/part_2" target="_blank">The source code</a> is on github.</p>

<h1 id="testing-our-engine">Testing Our Engine</h1>

<p><strong><a href="https://github.com/amrani/rails_modular_monolith_demo/tree/master/part_2" target="_blank">Source Code</a></strong></p>

<p>One of the benefits of a modular monolith is the ease of testing. However, each engine must be configured to test in isolation. It would be ideal to extend common test configuration to reduce setup time and keep things consistent across the application. We extracted our config into a gem, <code class="language-plaintext highlighter-rouge">common_testing</code>.</p>

<p>Since <code class="language-plaintext highlighter-rouge">common_testing</code> is opinionated and can vary across products we use it as a local gem. The gem lives in our host app’s<code class="language-plaintext highlighter-rouge">/gems</code> folder. Alternatively, you can read <a href="/blog/testing-an-engine-with-rspec/">Adding rspec to a rails engine</a>.</p>

<p>Let’s clone <a href="https://github.com/amrani/common_testing" target="_blank">common_testing</a> into our gems folder.</p>

<div class="language-zsh highlighter-rouge"><div class="highlight"><pre class="highlight"><code>./host_app <span class="nv">$ </span><span class="nb">mkdir</span> <span class="nt">-p</span> ./gems
./host_app <span class="nv">$ </span><span class="nb">cd</span> ./gems
./host_app/gems <span class="nv">$ </span>git clone https://github.com/amrani/common_testing.git
</code></pre></div></div>

<p>Bundle and remove git.</p>

<div class="language-zsh highlighter-rouge"><div class="highlight"><pre class="highlight"><code>./host_app/gems <span class="nv">$ </span><span class="nb">cd</span> ./common_testing
./host_app/gems/common_testing <span class="nv">$ </span><span class="nb">rm</span> <span class="nt">-rf</span> .git
./host_app/gems/common_testing <span class="nv">$ </span>bundle <span class="nb">install</span>
</code></pre></div></div>

<p>You will find our shared rails and spec helpers in the lib folder.</p>

<p>Let’s add this gem to our <a href="https://github.com/amrani/rails_modular_monolith_demo/tree/master/part_one/host_app/engines/connect_by" target="_blank">ConnectBy engine</a>.</p>

<div class="language-ruby highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1"># engines/connect_by/Gemfile</span>

<span class="n">group</span> <span class="ss">:development</span><span class="p">,</span> <span class="ss">:test</span> <span class="k">do</span>
  <span class="n">gem</span> <span class="s2">"common_testing"</span><span class="p">,</span> <span class="ss">path: </span><span class="s2">"../../gems/common_testing"</span>
<span class="k">end</span>
</code></pre></div></div>

<div class="language-ruby highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1"># engines/connect_by/connect_by.gemspec</span>
<span class="n">spec</span><span class="p">.</span><span class="nf">add_development_dependency</span> <span class="s2">"common_testing"</span>
</code></pre></div></div>

<div class="language-zsh highlighter-rouge"><div class="highlight"><pre class="highlight"><code>./host_app/engines/connect_by <span class="nv">$ </span>bundle <span class="nb">install</span>
</code></pre></div></div>

<p>Create the engine specific rails and spec helper. Then we can load the shared helper’s from the <code class="language-plaintext highlighter-rouge">common_testing</code> gem.</p>

<div class="language-ruby highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1"># engines/connect_by/spec/rails_helper.rb</span>

<span class="no">ENGINE_ROOT</span> <span class="o">=</span> <span class="no">Pathname</span><span class="p">.</span><span class="nf">new</span><span class="p">(</span><span class="no">File</span><span class="p">.</span><span class="nf">expand_path</span><span class="p">(</span><span class="s2">".."</span><span class="p">,</span> <span class="n">__dir__</span><span class="p">))</span>
<span class="no">ENV</span><span class="p">[</span><span class="s2">"RAILS_ENV"</span><span class="p">]</span> <span class="o">=</span> <span class="s2">"test"</span>
<span class="nb">require</span> <span class="s2">"common_testing/shared_rails_helper"</span>
</code></pre></div></div>

<div class="language-ruby highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1"># engines/connect_by/spec/spec_helper.rb</span>

<span class="nb">require</span> <span class="s2">"bundler/setup"</span>
<span class="nb">require</span> <span class="s2">"common_testing/shared_spec_helper"</span>

</code></pre></div></div>

<p>Add a <code class="language-plaintext highlighter-rouge">.rspec</code> config file and require our local spec-helper.</p>
<div class="language-zsh highlighter-rouge"><div class="highlight"><pre class="highlight"><code>./host_app/engines/connect_by <span class="nv">$ </span><span class="nb">echo</span> <span class="s2">"--require spec_helper"</span> <span class="o">&gt;</span> .rspec
</code></pre></div></div>

<p>Check if everything is working by running <code class="language-plaintext highlighter-rouge">rspec spec</code> in your engines root</p>

<div class="language-zsh highlighter-rouge"><div class="highlight"><pre class="highlight"><code>./host_app/engines/connect_by <span class="nv">$ </span>rspec spec
No examples found.

Finished <span class="k">in </span>0.00026 seconds <span class="o">(</span>files took 0.08725 seconds to load<span class="o">)</span>
0 examples, 0 failures
</code></pre></div></div>

<p>Now we should add a test.</p>

<div class="language-ruby highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1"># engines/connect_by/spec/models/connect_by/user_spec.rb</span>

<span class="nb">require</span> <span class="s2">"rails_helper"</span>
<span class="no">RSpec</span><span class="p">.</span><span class="nf">describe</span> <span class="no">ConnectBy</span><span class="o">::</span><span class="no">User</span><span class="p">,</span> <span class="ss">type: :model</span> <span class="k">do</span>
  <span class="n">it</span> <span class="p">{</span> <span class="n">expect</span><span class="p">(</span><span class="kp">true</span><span class="p">).</span><span class="nf">to</span> <span class="n">be_truthy</span> <span class="p">}</span>
<span class="k">end</span>
</code></pre></div></div>

<p><code class="language-plaintext highlighter-rouge">APP_RAKEFILE</code> is configured by <code class="language-plaintext highlighter-rouge">./engines/connect_by/Rakefile</code> to use dummy app’s. That way we can run our migrations in the engine’s root.</p>

<p>When we generated <code class="language-plaintext highlighter-rouge">connect_by</code>, we used the option <code class="language-plaintext highlighter-rouge">--dummy_path=spec/dummy</code>. Your dummy app should be in <code class="language-plaintext highlighter-rouge">./engines/connect_by/spec/dummy</code>.</p>

<p><strong>NOTE:</strong> If you didn’t, you will need to setup a dummy app and update your engine’s Rakefile.</p>

<div class="language-ruby highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1"># engines/connect_by/Rakefile</span>
<span class="no">APP_RAKEFILE</span> <span class="o">=</span> <span class="no">File</span><span class="p">.</span><span class="nf">expand_path</span><span class="p">(</span><span class="s2">"spec/dummy/Rakefile"</span><span class="p">,</span> <span class="n">__dir__</span><span class="p">)</span>
<span class="nb">load</span> <span class="s2">"rails/tasks/engine.rake"</span>
</code></pre></div></div>

<p><strong>Setup the database</strong></p>

<p>The engine’s dummy app, by default, prepends each database with <em>dummy_app</em>. To avoid name collisions with another engine dummy app, let’s alter the <code class="language-plaintext highlighter-rouge">database.yml</code>. I’ll use a format with <code class="language-plaintext highlighter-rouge">app_name</code>, <code class="language-plaintext highlighter-rouge">engine_name</code>, <code class="language-plaintext highlighter-rouge">"dummy_app"</code>, and <code class="language-plaintext highlighter-rouge">env</code>,</p>

<div class="language-yaml highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1"># ./engines/connect_by/spec/dummy/config/database.yml</span>
<span class="na">test</span><span class="pi">:</span>
  <span class="na">&lt;&lt;</span><span class="pi">:</span> <span class="nv">*default</span>
  <span class="na">database</span><span class="pi">:</span> <span class="s">host_app_connect_by_dummy_test</span>
</code></pre></div></div>

<p>Now setup our test db and run migrations.</p>

<div class="language-zsh highlighter-rouge"><div class="highlight"><pre class="highlight"><code>./host_app/engines/connect_by <span class="nv">$ RAILS_ENV</span><span class="o">=</span><span class="nb">test </span>rails db:setup
./host_app/engines/connect_by <span class="nv">$ </span>rspec spec
<span class="nb">.</span>

Finished <span class="k">in </span>0.02621 seconds <span class="o">(</span>files took 1.07 seconds to load<span class="o">)</span>
1 example, 0 failures
</code></pre></div></div>

<p><strong>Factory Bot</strong></p>

<p>I’ll add to my engine’s generators to use <code class="language-plaintext highlighter-rouge">factory-bot</code>.</p>

<div class="language-ruby highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">module</span> <span class="nn">ConnectBy</span>
  <span class="k">class</span> <span class="nc">Engine</span> <span class="o">&lt;</span> <span class="o">::</span><span class="no">Rails</span><span class="o">::</span><span class="no">Engine</span>
    <span class="o">...</span>

    <span class="n">config</span><span class="p">.</span><span class="nf">generators</span> <span class="k">do</span> <span class="o">|</span><span class="n">g</span><span class="o">|</span>
      <span class="n">g</span><span class="p">.</span><span class="nf">test_framework</span> <span class="ss">:rspec</span>
      <span class="n">g</span><span class="p">.</span><span class="nf">fixture_replacement</span> <span class="ss">:factory_bot</span>
      <span class="n">g</span><span class="p">.</span><span class="nf">factory_bot</span> <span class="ss">dir: </span><span class="s2">"spec/factories"</span>
    <span class="k">end</span>
</code></pre></div></div>

<h2 id="takeaway">Takeaway</h2>

<p>We added <code class="language-plaintext highlighter-rouge">rspec</code> and <code class="language-plaintext highlighter-rouge">factory-bot</code> to a rails 6 engine. Our shared configuration and dependencies were added to a local gem and referenced by our engine.</p>

<p>The <strong><a href="https://github.com/amrani/rails_modular_monolith_demo/tree/master/part_2" target="_blank">source code</a></strong> for this part is on github.</p>

<h2 id="next-steps">Next Steps</h2>

<p>In <a href="/blog/configure-rails-engine/">Part 3</a>, we will cover how we pass host app configuration options to our engine.</p>

<ul>
  <li><a href="/blog/create-user-rails-engine/">Part 1 - Create Your First Rails Engine</a></li>
  <li><a href="/blog/testing-modular-monolith-engines/">Part 2 - Test Your First Rails Engine</a></li>
  <li><a href="/blog/configure-rails-engine/">Part 3 - Configure Your First Rails Engine</a></li>
</ul>

<h2 id="useful-resources">Useful Resources</h2>

<p>I have <a href="/modular-monolith-resources/">compiled a list</a> of useful resources for rails engines and the modular monolith architecture.</p>

<h1 id="scale-with-rails-engines">Scale With Rails Engines</h1>

<p>Need help scaling your rails application with a modular monolith? <a href="/contact">Talk to us</a></p>

<hr />

<p> </p>

<p>Found this useful? Have a suggestion? Get in touch at <code class="language-plaintext highlighter-rouge">blog@hocnest.com</code>.</p>]]></content><author><name>David Amrani</name></author><category term="rails" /><category term="architecture" /><category term="engines" /><category term="rspec" /><category term="rmm" /><summary type="html"><![CDATA[Setup your test suite for your rails engine's. Part two of three focusing on testing, rspec, and factories for engines in a rails modular monolith.]]></summary><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://www.hocnest.com/img/services_dev_ops.png" /><media:content medium="image" url="https://www.hocnest.com/img/services_dev_ops.png" xmlns:media="http://search.yahoo.com/mrss/" /></entry><entry><title type="html">Create Your First Rails Engine</title><link href="https://www.hocnest.com/blog/create-user-rails-engine/" rel="alternate" type="text/html" title="Create Your First Rails Engine" /><published>2020-07-03T01:38:00-04:00</published><updated>2020-07-03T01:38:00-04:00</updated><id>https://www.hocnest.com/blog/create-user-rails-engine</id><content type="html" xml:base="https://www.hocnest.com/blog/create-user-rails-engine/"><![CDATA[<p>Ruby on Rails is a popular web framework known for rapid development backed by a great community. This post is intended to introduce and encourage you to build a more modular rails application. I maintain a <a href="/modular-monolith-resources/">collection of resources</a> if you’d like to learn more.</p>

<h1 id="creating-the-engine">Creating the Engine</h1>

<p>Most applications require user authentication so I think that would be a great first engine to create. I’m going to walk you through the creation of <code class="language-plaintext highlighter-rouge">ConnectBy</code>.</p>

<p><strong>Note:</strong> Credit for the naming conventions here goes to <a href="https://evilmartians.com/" target="_blank">Vlad and the Evil Martians</a>. You can check out his talk at <a href="https://noti.st/palkan/VWPOSd/between-monoliths-and-microservices" target="_blank">RailsConf 2020</a>.</p>

<h2 id="the-host">The Host</h2>

<p>I’ll refer to our rails app as the <strong>host application</strong>.</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>rails new host_app --database postgresql
</code></pre></div></div>

<p>We will install <a href="https://github.com/heartcombo/devise" target="_blank">Devise</a> in our <code class="language-plaintext highlighter-rouge">ConnectBy</code> engine. Let’s get started.</p>

<h2 id="generate-the-plugin">Generate the plugin</h2>
<p>Our engines are installed locally in <code class="language-plaintext highlighter-rouge">/engines</code> and gems in <code class="language-plaintext highlighter-rouge">/gems</code>. Run the rails plugin generator from the host’s root.</p>

<p><em>(using whitespace for clarity)</em></p>

<div class="language-zsh highlighter-rouge"><div class="highlight"><pre class="highlight"><code>./host_app <span class="nv">$ </span>rails plugin new engines/connect_by
              <span class="nt">--mountable</span>
              <span class="nt">--database</span> postgresql
              <span class="nt">--skip-git</span>
              <span class="nt">--skip-keeps</span>
              <span class="nt">--skip-action-text</span>
              <span class="nt">--skip-action-cable</span>
              <span class="nt">--skip-sprockets</span>
              <span class="nt">--skip-javascript</span>
              <span class="nt">--skip-turbolinks</span>
              <span class="nt">--skip-test</span>
              <span class="nt">--skip-system-test</span>
              <span class="nt">--skip-gemfile-entry</span>
              <span class="nt">--dummy_path</span><span class="o">=</span>spec/dummy
</code></pre></div></div>

<p><strong>Flags explained</strong></p>

<p>Skip setting up <code class="language-plaintext highlighter-rouge">test_unit</code> and create a dummy app that we will later use with rspec.</p>
<div class="language-zsh highlighter-rouge"><div class="highlight"><pre class="highlight"><code>  <span class="nt">--skip-test</span>
  <span class="nt">--skip-system-test</span>
  <span class="nt">--dummy_path</span><span class="o">=</span>spec/dummy
</code></pre></div></div>

<p>Our host app will dynamically load all of our engines.</p>
<div class="language-zsh highlighter-rouge"><div class="highlight"><pre class="highlight"><code>  <span class="nt">--skip-gemfile-entry</span>
</code></pre></div></div>

<p>Our frontend won’t live in our engine.</p>
<div class="language-zsh highlighter-rouge"><div class="highlight"><pre class="highlight"><code>  <span class="nt">--skip-action-cable</span>
  <span class="nt">--skip-sprockets</span>
  <span class="nt">--skip-javascript</span>
  <span class="nt">--skip-turbolinks</span>
</code></pre></div></div>

<p><strong>Version Management</strong></p>

<p>Add a rails-version file to our host app so each engine can reference it.</p>

<div class="language-zsh highlighter-rouge"><div class="highlight"><pre class="highlight"><code>./host_app <span class="nv">$ </span><span class="nb">echo</span> <span class="s2">"6.0.3.2"</span> <span class="o">&gt;</span> .rails-version
</code></pre></div></div>

<p>Update the gemspec</p>

<script src="https://gist.github.com/amrani/e2667aa22db4eb39526c221aead0fe1b.js"></script>

<p>Load our engine in the host application’s gemfile.</p>

<div class="language-ruby highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1"># Gemfile</span>

<span class="no">Dir</span><span class="p">.</span><span class="nf">glob</span><span class="p">(</span><span class="no">File</span><span class="p">.</span><span class="nf">expand_path</span><span class="p">(</span><span class="s2">"../engines/*"</span><span class="p">,</span> <span class="kp">__FILE__</span><span class="p">)).</span><span class="nf">each</span> <span class="k">do</span> <span class="o">|</span><span class="n">path</span><span class="o">|</span>
  <span class="n">gem</span> <span class="no">File</span><span class="p">.</span><span class="nf">basename</span><span class="p">(</span><span class="n">path</span><span class="p">),</span> <span class="ss">path: </span><span class="n">path</span>
<span class="k">end</span>
</code></pre></div></div>

<h2 id="install-devise">Install Devise</h2>
<p>Review devise’s latest <a href="https://github.com/heartcombo/devise#getting-started" target="_blank">getting start instructions</a> and use their <a href="https://github.com/heartcombo/devise/wiki/How-To:-Use-devise-inside-a-mountable-engine" target="_blank">devise inside a mountable engine</a> wiki as an additional resource.</p>

<p>Add devise to our engine’s gemfile.</p>

<div class="language-ruby highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1"># engines/connect_by/Gemfile</span>
<span class="n">gem</span> <span class="s2">"devise"</span><span class="p">,</span> <span class="s2">"~&gt; 4.7.1"</span>
</code></pre></div></div>

<p>Load devise.</p>

<div class="language-ruby highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1"># engines/connect_by/lib/connect_by.rb</span>

<span class="nb">require</span> <span class="s2">"connect_by/version"</span>

<span class="k">module</span> <span class="nn">ConnectBy</span>
<span class="k">end</span>

<span class="nb">require</span> <span class="s2">"devise"</span>
<span class="nb">require</span> <span class="s2">"connect_by/engine"</span>
</code></pre></div></div>

<p>Bundle <code class="language-plaintext highlighter-rouge">connect_by</code> and our host.</p>
<div class="language-zsh highlighter-rouge"><div class="highlight"><pre class="highlight"><code>./host_app <span class="nv">$ </span>bundle <span class="nb">install</span>
</code></pre></div></div>

<div class="language-zsh highlighter-rouge"><div class="highlight"><pre class="highlight"><code>./host_app/engines/connect_by <span class="nv">$ </span>bundle <span class="nb">install</span>
</code></pre></div></div>

<p>Install devise and create our user model.</p>
<div class="language-zsh highlighter-rouge"><div class="highlight"><pre class="highlight"><code>./host_app/engines/connect_by <span class="nv">$ </span>rails generate devise:install
./host_app/engines/connect_by <span class="nv">$ </span>rails generate devise user
</code></pre></div></div>

<p>Update our devise configuration.</p>
<div class="language-ruby highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1"># engines/connect_by/initializers/devise.rb</span>
<span class="n">config</span><span class="p">.</span><span class="nf">parent_controller</span> <span class="o">=</span> <span class="s1">'ConnectBy::ApplicationController'</span>
<span class="n">config</span><span class="p">.</span><span class="nf">router_name</span> <span class="o">=</span> <span class="ss">:connect_by</span>
</code></pre></div></div>

<p>Install our new migrations on the host application.</p>
<div class="language-zsh highlighter-rouge"><div class="highlight"><pre class="highlight"><code>./host_app <span class="nv">$ </span>rails connect_by:install:migrations
</code></pre></div></div>

<p>Migrate your host app’s database.</p>
<div class="language-zsh highlighter-rouge"><div class="highlight"><pre class="highlight"><code>./host_app <span class="nv">$ </span>rails db:create db:migrate
</code></pre></div></div>

<p>Mount our engine’s route in the host.</p>
<div class="language-ruby highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1"># config/routes.rb</span>

<span class="no">Rails</span><span class="p">.</span><span class="nf">application</span><span class="p">.</span><span class="nf">routes</span><span class="p">.</span><span class="nf">draw</span> <span class="k">do</span>
  <span class="n">mount</span> <span class="no">ConnectBy</span><span class="o">::</span><span class="no">Engine</span><span class="p">,</span> <span class="ss">at: </span><span class="s2">"/a"</span>
<span class="k">end</span>
</code></pre></div></div>

<p>We are creating an isolate namespaced engine so we need to tell devise that we are using their controllers in their <code class="language-plaintext highlighter-rouge">module</code>.</p>
<div class="language-ruby highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1"># engines/connect_by/config/routes.rb</span>
<span class="n">devise_for</span> <span class="ss">:users</span><span class="p">,</span>
  <span class="ss">class_name: </span><span class="s2">"ConnectBy::User"</span><span class="p">,</span>
  <span class="ss">module: :devise</span>
</code></pre></div></div>

<h2 id="frontend">Frontend</h2>

<p>I’ll drop the frontend from <code class="language-plaintext highlighter-rouge">ConnectBy</code> to avoid taking away from the tutorial. Isolated frontends with Webpacker 4 can get very involved (<a href="https://github.com/rails/webpacker/issues/348" target="_blank">How to use webpacker from within engines?</a>).</p>

<p>Remove assets and view layouts from the engine.</p>

<div class="language-zsh highlighter-rouge"><div class="highlight"><pre class="highlight"><code>./host_app/engines/connect_by <span class="nv">$ </span><span class="nb">rm</span> <span class="nt">-rf</span> ./app/assets
./host_app/engines/connect_by <span class="nv">$ </span><span class="nb">rm</span> <span class="nt">-rf</span> ./app/views/layouts
</code></pre></div></div>

<p>Start up the server and navigate to <code class="language-plaintext highlighter-rouge">/a/users/sign_in</code> to confirm it worked.</p>

<h2 id="takeaway">Takeaway</h2>

<p>We took a modular approach and created a rails engine for our user account’s.</p>

<p>The <strong><a href="https://github.com/amrani/rails_modular_monolith_demo/tree/master/part_1" target="_blank">source code</a></strong> for this part is on github.</p>

<h2 id="next-steps">Next Steps</h2>

<p><a href="/blog/testing-modular-monolith-engines/">Part 2</a> focuses on setting up the test suite, specifically rspec.</p>

<ul>
  <li><a href="/blog/create-user-rails-engine/">Part 1 - Create Your First Rails Engine</a></li>
  <li><a href="/blog/testing-modular-monolith-engines/">Part 2 - Test Your First Rails Engine</a></li>
  <li><a href="/blog/configure-rails-engine/">Part 3 - Configure Your First Rails Engine</a></li>
</ul>

<h2 id="useful-resources">Useful Resources</h2>

<p>I have <a href="/modular-monolith-resources/">compiled a list</a> of useful resources for rails engines and the modular monolith architecture.</p>

<h1 id="scale-with-rails-engines">Scale With Rails Engines</h1>

<p>Need help scaling your rails application with a modular monolith? <a href="/contact">Talk to us</a></p>]]></content><author><name>David Amrani</name></author><category term="rails" /><category term="architecture" /><category term="engines" /><category term="devise" /><category term="authentication" /><category term="rmm" /><summary type="html"><![CDATA[Create your first ruby on rails engine tutorial. Part one of three working with engines in a rails modular monolith.]]></summary><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://www.hocnest.com/img/services_architecture.png" /><media:content medium="image" url="https://www.hocnest.com/img/services_architecture.png" xmlns:media="http://search.yahoo.com/mrss/" /></entry><entry><title type="html">Unique Robot Path</title><link href="https://www.hocnest.com/blog/unique-robot-path/" rel="alternate" type="text/html" title="Unique Robot Path" /><published>2020-04-14T10:37:00-04:00</published><updated>2020-04-14T10:37:00-04:00</updated><id>https://www.hocnest.com/blog/unique-robot-path</id><content type="html" xml:base="https://www.hocnest.com/blog/unique-robot-path/"><![CDATA[<h1 id="unique-robot-paths">Unique Robot Paths</h1>

<p>Today I’m going to go through a fun algorithm problem called Unique Robot Paths. Here’s the problem statement:</p>

<blockquote>
  <p>A robot is located at the top left corner of a m x n grid. Where m is the number of rows and n is the number of columns. The robot can only move either down or to the right. The robot’s destination is the bottom-right corner of the grid.</p>
</blockquote>

<p>How many possible unique paths exist?</p>

<p><img src="/img/unique_robot_paths/image1.png" alt="A robot on a 3 by 5 grid" title="3x5 Grid" /></p>

<p>One way to solve the problem is to recursively count all paths. However, the time complexity this solution is exponential, <strong>O(2^n)</strong>.</p>

<h2 id="can-we-do-better">Can we do better?</h2>

<p>Since this problem has these 2 important properties.</p>

<ol>
  <li>Overlapping sub-problems</li>
  <li>Optimal substructure</li>
</ol>

<p>These 2 properties allow us to use Dynamic Programming to solve this problem.</p>

<p>Let’s consider a smaller grid that is <strong>3 x 2</strong> in size.</p>

<p><img src="/img/unique_robot_paths/image3.png" alt="A robot on a 3 by 2 grid" title="3x2 Grid" /></p>

<p>There are 3 ways to get to the bottom right. If we break the problem down, we can see how we can arrive at the answer.</p>

<p>Because the robot can only move down or right, the robot can only be one way to move to the right cell, and from there, 1 way to move to the bottom cell. This is one path to reach the destination.</p>

<p>Another path the robot could take, is the robot could move down 1 cell from the starting point and from there, move 1 space to the right.</p>

<p>And the third path the robot could take, is the to first move down 1 cell, move right 1 cell, and then finally, move down 1 cell to the finish.</p>

<p><img src="/img/unique_robot_paths/image5.png" alt="Guided paths for a robot on a 3 by 2 grid" title="3x2 Grid Paths" /></p>

<p>If you take a look at the grid, there’s a pattern — the number of ways to get to a certain cell equals the number of ways to get to its left cell PLUS the number of ways to get to the cell above it. Or expressed as an equation:</p>

<p><img src="/img/unique_robot_paths/image7.png" alt="Unique Path Formula" title="Unique Path Formula" /></p>

<p>So from his pattern, we can derive a solution.</p>

<p><img src="/img/unique_robot_paths/image8.png" alt="A robot on a 3 by 2 grid with values" title="3x2 Grid Values" /></p>

<p>Going back to the initial problem with the <strong>3 x 5</strong> grid. Let’s fill out this grid and find the solution!</p>

<p>We know for the top row of cells there is only 1 way to reach each of the cells <strong>(m=0)</strong>, and also the same is true for the left most column <strong>(n=0)</strong>.</p>

<p><img src="/img/unique_robot_paths/image10.png" alt="A robot on a 3 by 5 grid with path values" title="3x5 Grid Path Values" /></p>

<p>From here, it’s easy to fill out the rest of the cells.</p>

<p><img src="/img/unique_robot_paths/image12.png" alt="A robot on a 3 by 5 grid with grid values" title="3x5 Grid Values" /></p>

<p>So for a 5 x 3 grid, there are 15 unique paths that the robot can take.</p>

<p> 
 </p>
<h3 id="lets-code-up-a-solution-in-javascript">Let’s code up a solution in JavaScript!</h3>

<div class="language-javascript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="cm">/**
 * @param {number} m
 * @param {number} n
 * @return {number}
 */</span>
<span class="kd">var</span> <span class="nx">uniquePaths</span> <span class="o">=</span> <span class="kd">function</span><span class="p">(</span><span class="nx">m</span><span class="p">,</span> <span class="nx">n</span><span class="p">)</span> <span class="p">{</span>
  <span class="kd">let</span> <span class="nx">storage</span> <span class="o">=</span> <span class="k">new</span> <span class="nb">Array</span><span class="p">(</span><span class="nx">m</span><span class="p">).</span><span class="nx">fill</span><span class="p">(</span><span class="k">new</span> <span class="nb">Array</span><span class="p">(</span><span class="nx">n</span><span class="p">));</span>

  <span class="c1">// fill the left most column of the storage matrix with 1's</span>
  <span class="k">for</span><span class="p">(</span><span class="kd">let</span> <span class="nx">i</span><span class="o">=</span><span class="mi">0</span><span class="p">;</span> <span class="nx">I</span> <span class="o">&lt;</span> <span class="nx">m</span><span class="p">;</span> <span class="nx">i</span><span class="o">++</span><span class="p">)</span> <span class="p">{</span>
    <span class="nx">storage</span><span class="p">[</span><span class="nx">i</span><span class="p">][</span><span class="mi">0</span><span class="p">]</span> <span class="o">=</span> <span class="mi">1</span><span class="p">;</span>
  <span class="p">}</span>

  <span class="c1">// fill the top most row of the storage matrix with 1's</span>
  <span class="k">for</span><span class="p">(</span><span class="kd">let</span> <span class="nx">j</span><span class="o">=</span><span class="mi">0</span><span class="p">;</span> <span class="nx">j</span> <span class="o">&lt;</span> <span class="nx">n</span><span class="p">;</span> <span class="nx">j</span><span class="o">++</span><span class="p">)</span> <span class="p">{</span>
    <span class="nx">storage</span><span class="p">[</span><span class="mi">0</span><span class="p">][</span><span class="nx">j</span><span class="p">]</span> <span class="o">=</span> <span class="mi">1</span><span class="p">;</span>
  <span class="p">}</span>

  <span class="c1">// iterate through the rest of the matrix and fill up the values</span>
  <span class="k">for</span><span class="p">(</span><span class="kd">let</span> <span class="nx">i</span><span class="o">=</span><span class="mi">1</span><span class="p">;</span> <span class="nx">I</span> <span class="o">&lt;</span> <span class="nx">m</span><span class="p">;</span> <span class="nx">i</span><span class="o">++</span><span class="p">)</span> <span class="p">{</span>
    <span class="k">for</span><span class="p">(</span><span class="kd">let</span> <span class="nx">j</span><span class="o">=</span><span class="mi">1</span><span class="p">;</span> <span class="nx">j</span> <span class="o">&lt;</span> <span class="nx">n</span><span class="p">;</span> <span class="nx">j</span><span class="o">++</span><span class="p">)</span> <span class="p">{</span>
      <span class="nx">storage</span><span class="p">[</span><span class="nx">i</span><span class="p">][</span><span class="nx">j</span><span class="p">]</span> <span class="o">=</span> <span class="nx">storage</span><span class="p">[</span><span class="nx">i</span><span class="o">-</span><span class="mi">1</span><span class="p">][</span><span class="nx">j</span><span class="p">]</span> <span class="o">+</span> <span class="nx">storage</span><span class="p">[</span><span class="nx">i</span><span class="p">][</span><span class="nx">j</span><span class="o">-</span><span class="mi">1</span><span class="p">];</span>
    <span class="p">}</span>
  <span class="p">}</span>

  <span class="c1">// return the bottom right cell's value</span>
  <span class="k">return</span> <span class="nx">storage</span><span class="p">[</span><span class="nx">m</span><span class="o">-</span><span class="mi">1</span><span class="p">][</span><span class="nx">n</span><span class="o">-</span><span class="mi">1</span><span class="p">];</span>
<span class="p">};</span>
</code></pre></div></div>

<p>The run time for this solution is <strong>O(m x n)</strong> and the space complexity is also <strong>O(m x n)</strong> . A dramatic time complexity reduction for space trade-off. The above solution is intuitive, but there is a further optimization that reduces the space complexity to <strong>O(m)</strong>.</p>

<div class="language-javascript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="cm">/**
 * @param {number} m
 * @param {number} n
 * @return {number}
 */</span>
<span class="kd">var</span> <span class="nx">uniquePaths</span> <span class="o">=</span> <span class="kd">function</span><span class="p">(</span><span class="nx">m</span><span class="p">,</span> <span class="nx">n</span><span class="p">)</span> <span class="p">{</span>
  <span class="kd">let</span> <span class="nx">storage</span> <span class="o">=</span> <span class="k">new</span> <span class="nb">Array</span><span class="p">(</span><span class="nx">n</span><span class="p">).</span><span class="nx">fill</span><span class="p">(</span><span class="mi">0</span><span class="p">);</span>

  <span class="nx">storage</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="o">=</span> <span class="mi">1</span><span class="p">;</span>

  <span class="k">for</span><span class="p">(</span><span class="kd">let</span> <span class="nx">i</span><span class="o">=</span><span class="mi">0</span><span class="p">;</span> <span class="nx">i</span> <span class="o">&lt;</span> <span class="nx">m</span><span class="p">;</span> <span class="nx">i</span><span class="o">++</span><span class="p">)</span> <span class="p">{</span>
    <span class="k">for</span><span class="p">(</span><span class="kd">let</span> <span class="nx">j</span><span class="o">=</span><span class="mi">1</span><span class="p">;</span> <span class="nx">j</span> <span class="o">&lt;</span> <span class="nx">n</span><span class="p">;</span> <span class="nx">j</span><span class="o">++</span><span class="p">)</span> <span class="p">{</span>
      <span class="nx">storage</span><span class="p">[</span><span class="nx">j</span><span class="p">]</span> <span class="o">+=</span> <span class="nx">storage</span><span class="p">[</span><span class="nx">j</span><span class="o">-</span><span class="mi">1</span><span class="p">];</span>
    <span class="p">}</span>
  <span class="p">}</span>

  <span class="k">return</span> <span class="nx">storage</span><span class="p">[</span><span class="nx">n</span><span class="o">-</span><span class="mi">1</span><span class="p">];</span>
<span class="p">};</span>
</code></pre></div></div>

<p> </p>
<h4 id="did-you-like-this-article-check-out-these-too">Did you like this article? Check out these too.</h4>
<ul>
  <li><a href="/blog/css-grid-basics/">An introduction to CSS Grid and an overview on the basics</a></li>
  <li><a href="/blog/why-use-typescript/">Why use Typescript?</a></li>
</ul>

<hr />

<p> </p>

<p>Found this useful? Have a suggestion? Get in touch at <code class="language-plaintext highlighter-rouge">blog@hocnest.com</code>.</p>]]></content><author><name>Johnny Chen</name></author><category term="javascript" /><category term="algorithm" /><summary type="html"><![CDATA[Walk-through a solution for the Unique Robot Paths algorithm using JavaScript.]]></summary><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://www.hocnest.com/img/avatar@2x.png" /><media:content medium="image" url="https://www.hocnest.com/img/avatar@2x.png" xmlns:media="http://search.yahoo.com/mrss/" /></entry><entry><title type="html">CSS Grid Basics</title><link href="https://www.hocnest.com/blog/css-grid-basics/" rel="alternate" type="text/html" title="CSS Grid Basics" /><published>2020-02-05T20:55:00-05:00</published><updated>2020-02-05T20:55:00-05:00</updated><id>https://www.hocnest.com/blog/css-grid-basics</id><content type="html" xml:base="https://www.hocnest.com/blog/css-grid-basics/"><![CDATA[<h1 id="css-grid-basics">CSS Grid Basics</h1>

<p>CSS has come a long way. I remember in 2013, I was on a project developing a products listing page for an electronic components e-commerce site. The page had tooltips, multiple tabs, dropdown for distributors, and pricing data all on one page. The UX was especially important as the primary users of this e-commerce site were people who were familiar with purchasing electronic components for industries such as Oil &amp; Gas, Data Centers, Medical &amp; Healthcare, and much more. Grids weren’t adopted widely then and we also had to support IE all the way down to IE6. So floats, inline-block, and negative margins/paddings it was!</p>

<p>Then came Flexbox which was intended for laying out elements in a single dimension - a column or row. But what about two dimensional layouts? For that we now have Grid.</p>

<p>As of now, Grid is adopted by most major browsers without vendor prefixes. Without further ado, let’s dive into the basics.</p>

<h2 id="grid-terminology">Grid Terminology</h2>

<p>Here’s some terminology to get started.</p>

<p><strong>Grid Container</strong> -  The outer element whose display is set to display: grid</p>

<p><strong>Grid Item</strong> - The direct child elements of the Grid Container</p>

<p><strong>Grid Line</strong> - the lines of the grid including the outer borders</p>

<p><strong>Grid Cell</strong> - a single “unit” of the grid. It’s the space between two adjacent row and two adjacent column grid lines</p>

<p><strong>Grid Track</strong> - a single row or column of grid cells or the space between two adjacent grid lines</p>

<p><strong>Grid Area</strong> - space surrounded by four grid lines</p>

<p>We’ll define a container element as the grid with display: grid and set the sizes of the columns and rows with grid-template-columns and grid-template-rows.</p>

<p> 
 </p>
<p class="codepen" data-height="265" data-theme-id="light" data-default-tab="css,result" data-user="mcjcc" data-slug-hash="BayEBzJ" style="height: 265px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 3em 0; padding: 1em;" data-pen-title="CSS Grids: &amp;quot;fr&amp;quot; example">
  <span>See the Pen <a href="https://codepen.io/mcjcc/pen/BayEBzJ">
  CSS Grids: &quot;fr&quot; example</a> by Johnny Chen (<a href="https://codepen.io/mcjcc">@mcjcc</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async="" src="https://static.codepen.io/assets/embed/ei.js"></script>

<p> 
 </p>

<p>In this example, row grid tracks are 1fr tall and the column grid tracks are 1fr wide. Also, if your columns are all the same width and all your rows are the same height, there is a shorthand way to set the grid-template-columns/rows using the repeat keyword. The repeat keyword is a useful little function that allows you to write grid rules in a more compact form.</p>

<p>The fr unit of measurement or the fraction unit. If you’ve never seen this before, fr <em>“represents a fraction of the leftover space in the grid container.”</em> <a href="https://www.w3.org/TR/css3-grid-layout/#fr-unit" target="_blank">https://www.w3.org/TR/css3-grid-layout/#fr-unit</a>.</p>

<p>The browser automatically adjusts the sizes of the grid elements to fit the grid container. Let’s see what happens when we use a length value such as percentage.</p>

<p> 
 </p>
<p class="codepen" data-height="265" data-theme-id="light" data-default-tab="css,result" data-user="mcjcc" data-slug-hash="KKwOwvd" style="height: 265px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;" data-pen-title="CSS Grids: percentage example">
  <span>See the Pen <a href="https://codepen.io/mcjcc/pen/KKwOwvd">
  CSS Grids: percentage example</a> by Johnny Chen (<a href="https://codepen.io/mcjcc">@mcjcc</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async="" src="https://static.codepen.io/assets/embed/ei.js"></script>

<p> 
 </p>

<p>Using a length type unit doesn’t automatically adjust to the width of the container and causes the grid items to overflow. What we are telling the browser to do is set each grid item to 33% of the width and height AND have a 10px gap.</p>

<p>Grid can also be used to create a layout that may not traditionally be seen as a grid. In this example below, the “Holy Grail” layout is implemented with Grid.</p>

<p> 
 </p>
<p class="codepen" data-height="265" data-theme-id="light" data-default-tab="css,result" data-user="mcjcc" data-slug-hash="LYEvPLZ" style="height: 265px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;" data-pen-title="CSS Grid - Holy Grail">
  <span>See the Pen <a href="https://codepen.io/mcjcc/pen/LYEvPLZ">
  CSS Grid - Holy Grail</a> by Johnny Chen (<a href="https://codepen.io/mcjcc">@mcjcc</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async="" src="https://static.codepen.io/assets/embed/ei.js"></script>

<p> 
 </p>

<p>The Holy Grail layout with the gridlines displayed.</p>

<p>Grid have become my favorite way of creating layouts. The fr unit is a useful way to automatically size the grid items to the container. There is plenty of utility with Grid and this post just scratches the surface and is meant to give you an introduction. To learn more about what else you can do, check out one of my favorite resources for web docs: <a href="https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Grid_Layout" target="_blank">MDN</a></p>

<p> </p>
<h4 id="did-you-like-this-article-check-out-these-too">Did you like this article? Check out these too.</h4>
<ul>
  <li><a href="/blog/why-use-typescript/">Why use Typescript?</a></li>
  <li><a href="/blog/unique-robot-path/">Unique Robot Path</a></li>
</ul>

<hr />

<p> </p>

<p>Found this useful? Have a suggestion? Get in touch at <code class="language-plaintext highlighter-rouge">blog@hocnest.com</code>.</p>]]></content><author><name>Johnny Chen</name></author><category term="css" /><category term="css-grid" /><summary type="html"><![CDATA[An introduction to CSS Grid and an overview on the basics. Test the codepen examples for yourself!]]></summary><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://www.hocnest.com/img/avatar@2x.png" /><media:content medium="image" url="https://www.hocnest.com/img/avatar@2x.png" xmlns:media="http://search.yahoo.com/mrss/" /></entry><entry><title type="html">Why use Typescript?</title><link href="https://www.hocnest.com/blog/why-use-typescript/" rel="alternate" type="text/html" title="Why use Typescript?" /><published>2020-01-05T12:15:00-05:00</published><updated>2020-01-05T12:15:00-05:00</updated><id>https://www.hocnest.com/blog/why-use-typescript</id><content type="html" xml:base="https://www.hocnest.com/blog/why-use-typescript/"><![CDATA[<h1 id="why-we-use-typescript-on-our-front-end">Why we use TypeScript on our Front End</h1>

<p>TypeScript has been gaining in popularity in the past couple of years. Now what is TypeScript about? Here’s a little background, JavaScript is a dynamically-typed language. What that means is that the interpreter assigns variables a type at runtime depending on the value’s type. (e.g string, int) While this allows development to be arguably faster, it can slow your debugging process when facing production-level bugs. Onboarding new developers is another good reason for TypeScript. And in today’s modern distributed systems architectures, static typing allows a guarantee that individual pieces fit together.</p>

<p>Just how popular is TypeScript? According to State of JS’s 2019 developer survey — ~80% of JavaScript developers would like to learn TypeScript or would use it again. And in StackOverflow’s 2019 Developer Survey — TypeScript was the third most loved programming technology and the fourth most wanted programming technology.</p>

<p>When I first joined my current team, JSDoc was used to document the JavaScript function signatures. This was great at first, but as time went on, I noticed the comments weren’t entirely accurate and the previous maintainers had moved on to different projects or were working at a different company. I ended up suggesting refactoring the entire codebase and port it over to React with TypeScript.</p>

<p>Let’s dive in to some examples.</p>

<p><img src="/img/why_use_typescript/image_1.png" alt="An example of Typescript - screenshot of an IDE" title="Image" /></p>

<p>TypeScript does not change how your code behaves at runtime — instead it warns the developer straight inside their IDE’s.</p>

<p>With this example, the type checker understands that .toUpperCase() is a string method that does not exist on an Array.</p>

<p>Developer’s can also define their own types with the “interface” keyword. Interfaces allow you to define the shape of the data by assigning data types to properties such as ‘string’, ‘boolean’, and ‘number. It also allows you to specify whether a property is read-only or optional. One of the greatest benefits about Interfaces is that it prevents ambiguity when passing data around. Also, interfaces make it extremely easy to work with backend engineers to define how the data should arrive from the backend.</p>

<p><img src="/img/why_use_typescript/applydiscounterror.png" alt="Typescript compile error" title="Error 1" /></p>

<p>With this example, I’ve tried to apply a discount directly to the <code class="language-plaintext highlighter-rouge">price</code> property and notice how an error warns the user.</p>

<p><img src="/img/why_use_typescript/getproductweighterror.png" alt="Typescript compile error" title="Error 2" /></p>

<p>As I mentioned before, there may be some conditions where properties aren’t required. Here’s an example of the pattern. Notice the “?” denoting that the property is optional. The below code demonstrates an example how the type checker will warn the developer that a property could be undefined and that one may want to handle that scenario.</p>

<p>I’ve gone ahead and refactored the code a bit to get ride of the errors.</p>

<p><img src="/img/why_use_typescript/noerrors.png" alt="Typescript with no errors" title="No Errors" /></p>

<p>Finally, check out the compiled version of Typescript. Notice how it is just vanilla JavaScript which means there’s no overhead for the end user.</p>

<p><img src="/img/why_use_typescript/compiled.png" alt="Screenshot of a successful compile" title="Compiled" /></p>

<p>TypeScript integrates really well with other frontend frameworks such as React.</p>

<p>A simple <code class="language-plaintext highlighter-rouge">npm install --save-dev @types/react</code> Gets you started without much configuration required.</p>

<p>I was surprised by the number of tiny bugs that appeared when I started converting our codebase. There were plenty of misspelled properties and assumptions that an optional property existed. I spoke to some of the other engineers on different teams going through their own codebase conversion and found out they had similar experiences — which was nice to hear. TypeScript even has a handy tutorial on how to begin migrating your JavaScript codebase! (https://www.typescriptlang.org/docs/handbook/migrating-from-javascript.html)</p>

<p>Another great thing about TypeScript is that it is integrated very well with popular IDE’s. VSCode, Sublime, and Atom all have plugins that have autocomplete suggestions.</p>

<p>If you use Continuous Integration in your project, I recommend adding a TSLint pre-commit hook that automatically tests your TypeScript which means that when it comes time to do a code review for a pull request, we already have confidence that the structural dependencies are up to standards.</p>

<p>However, TypeScript is not without its downsides. It has training costs and people who have experience with strongly-typed languages usually pick up the syntax fairly quickly, but for people who do not, it can be a frustrating experience. A simple solution to this is to begin adding type declarations to some of the more simple pieces of code and build your way up to more complex structures such as inheritance.</p>

<p>So should you use TypeScript?
Here are some questions to consider:</p>
<ul>
  <li>Are your apps big? As your apps grow, TypeScript can help with reducing ambiguity and easier maintenance</li>
  <li>Do you work on a team? As a sole creator of an app, it’s easy to know what each api call does. After all, you’re the person who wrote all of them. However, when your team grows or if you have to look at functions written months ago, having TypeScript can help</li>
  <li>Are non-js developers going to write JS code? Developers who are used to say, Java or C#, will be more comfortable with the code and be more productive.</li>
</ul>

<p>To get started, check TypeScript’s very own tutorial. (https://www.typescriptlang.org/docs/tutorial.html).</p>

<p>If you enjoyed this post and found it helpful, share it with someone who may also find it useful!</p>

<h3 id="citations">Citations</h3>

<ul>
  <li><a href="https://2019.stateofjs.com/javascript-flavors/typescript/" target="_blank">stateofjs</a></li>
  <li><a href="https://insights.stackoverflow.com/survey/2019" target="_blank">stackoverflow</a></li>
</ul>

<p> </p>
<h4 id="did-you-like-this-article-check-out-these-too">Did you like this article? Check out these too.</h4>
<ul>
  <li><a href="/blog/css-grid-basics/">An introduction to CSS Grid and an overview on the basics</a></li>
  <li><a href="/blog/unique-robot-path/">Unique Robot Path</a></li>
</ul>

<hr />

<p> </p>

<p>Found this useful? Have a suggestion? Get in touch at <code class="language-plaintext highlighter-rouge">blog@hocnest.com</code>.</p>]]></content><author><name>Johnny Chen</name></author><category term="javascript" /><category term="typescript" /><summary type="html"><![CDATA[Learn more about Typescript, the benefits that come from using it, and how to get started.]]></summary><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://www.hocnest.com/img/logo_full.png" /><media:content medium="image" url="https://www.hocnest.com/img/logo_full.png" xmlns:media="http://search.yahoo.com/mrss/" /></entry><entry><title type="html">Creating Local Rails Engines</title><link href="https://www.hocnest.com/blog/creating-local-rails-engine/" rel="alternate" type="text/html" title="Creating Local Rails Engines" /><published>2019-08-11T07:29:00-04:00</published><updated>2019-08-11T07:29:00-04:00</updated><id>https://www.hocnest.com/blog/creating-local-rails-engine</id><content type="html" xml:base="https://www.hocnest.com/blog/creating-local-rails-engine/"><![CDATA[<h1 id="component-based-architecture">Component Based Architecture</h1>

<p>A component contains reusable business functionality that can be referenced and used by other components. Components can associate with one another by setting an explicit dependency. The collection of components and their dependencies can be diagrammed in a directed acyclic graph, a graph with no cycles. Meaning, no circular dependencies. For those of you experienced with React JS, you are already familiar with component based architecture.</p>

<h1 id="modular-approach-in-rails">Modular Approach in Rails</h1>

<p>Applying this pattern in Rails can be done with mountable engines. Your main application, often referred to as your host, will contain a folder we call <em>engines</em>. You can name the folder what ever you want. <code class="language-plaintext highlighter-rouge">components</code> is another good name. I prefer <code class="language-plaintext highlighter-rouge">engines</code> as we typically also generate a <code class="language-plaintext highlighter-rouge">gems</code> folder to differentiate between the two but unimportant for the scope of this post.</p>

<p>Nested within the engines folder will live these mountable engines we call components. It is made available to the host application just like any other gem, via the gemfile.</p>

<h1 id="creating-an-engine">Creating an Engine</h1>

<p>Considering a real world example for an app that needs to support generating reports: Lets create a <code class="language-plaintext highlighter-rouge">Reports</code> engine.</p>

<p>First step is to create the mountable engine. We do so by using the <em>rails plugin new</em> generator. The generator accepts a variety of options that you may want to use. See the full list by running <code class="language-plaintext highlighter-rouge">rails plugin --help</code>.</p>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>root <span class="nv">$ </span>rails plugin new engines/reports <span class="nt">--mountable</span> <span class="nt">-d</span> postgresql
</code></pre></div></div>

<p>The generator should have created a mini application in your <strong>engines/reports</strong> folder. It also should have modified your host application’s gemfile by appending:</p>
<div class="language-ruby highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">gem</span> <span class="s1">'reports'</span><span class="p">,</span> <span class="ss">path: </span><span class="s1">'engines/reports'</span>
</code></pre></div></div>

<p>I usually remove that line and add the engines dynamically like so:</p>

<div class="language-ruby highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="no">Dir</span><span class="p">.</span><span class="nf">glob</span><span class="p">(</span><span class="no">File</span><span class="p">.</span><span class="nf">expand_path</span><span class="p">(</span><span class="s1">'../engines/*'</span><span class="p">,</span> <span class="kp">__FILE__</span><span class="p">)).</span><span class="nf">each</span> <span class="k">do</span> <span class="o">|</span><span class="n">path</span><span class="o">|</span>
  <span class="n">gem</span> <span class="no">File</span><span class="p">.</span><span class="nf">basename</span><span class="p">(</span><span class="n">path</span><span class="p">),</span> <span class="ss">path: </span><span class="n">path</span>
<span class="k">end</span>
</code></pre></div></div>

<p>Go ahead and try to bundle from your host.</p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>root <span class="nv">$ </span>bundle <span class="nb">install

</span>You have one or more invalid gemspecs that need to be fixed.
The gemspec is not valid. Please fix this gemspec.
The validation error was <span class="s1">'"FIXME" or "TODO" is not a description'</span>
</code></pre></div></div>

<p>Even though we are creating a local gem we still need to complete the TODO’s in the gemspec. Modify <strong>host/engines/reports/reports.gemspec</strong> and ensure you can bundle from your host directory.</p>

<h1 id="create-our-first-model">Create Our First Model</h1>
<p>Now that we have an engine, we can go ahead create a model. If you recall, we used the <code class="language-plaintext highlighter-rouge">--mountable</code> option when creating the engine. That isolated the engine and name-spaced everything with <code class="language-plaintext highlighter-rouge">Reports</code>, including the database tables.</p>

<p>Navigate to the <strong>reports directory</strong> and create a <code class="language-plaintext highlighter-rouge">report</code> model.</p>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>root <span class="nv">$ </span><span class="nb">cd</span> ./engines/reports
root/engines/reports <span class="nv">$ </span>rails g model Report name data:text
</code></pre></div></div>

<p>Our new migration file exists within our reports engine <em>db/migrate</em> folder. Think of this migration file as the source of truth. The migration files are managed within the engine although they will also need to exist in the host application. We must copy our migration over to the host application. This is done by the railties install migration command.</p>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>root <span class="nv">$ </span>rails railties:install:migrations

Copied migration 20190811131059_create_reports_reports.reports.rb from reports
</code></pre></div></div>

<p>You should notice a few things:</p>
<ul>
  <li>The report table is name-spaced by reports. Table name is <code class="language-plaintext highlighter-rouge">reports_report</code></li>
  <li>The original <code class="language-plaintext highlighter-rouge">CreateReportsReports</code> migration file exists in the reports engine</li>
  <li>A copy of <code class="language-plaintext highlighter-rouge">CreateReportsReports</code> lives in the host application</li>
  <li>The original and copied migration file versions (time-stamps) are different</li>
</ul>

<p>It is safe to rerun the <em>railties install migration</em> command. It will only copy over new migrations.</p>

<p>From you host, migrate the database.</p>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>root <span class="nv">$ </span>rails db:migrate
</code></pre></div></div>

<h1 id="business-logic">Business Logic</h1>

<p>It is time to add some business logic to support generating a report. Add a file named <code class="language-plaintext highlighter-rouge">generator.rb</code>.</p>

<div class="language-ruby highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1"># root/engines/reports/lib/reports/generator.rb</span>

<span class="k">module</span> <span class="nn">Reports</span>
  <span class="k">class</span> <span class="nc">Generator</span>
    <span class="k">def</span> <span class="nc">self</span><span class="o">.</span><span class="nf">run</span><span class="p">(</span><span class="nb">name</span><span class="p">:)</span>

      <span class="c1"># Some meaningful code here</span>

      <span class="no">Report</span><span class="p">.</span><span class="nf">create</span><span class="p">(</span><span class="ss">name: </span><span class="nb">name</span><span class="p">)</span>
    <span class="k">end</span>
  <span class="k">end</span>
<span class="k">end</span>
</code></pre></div></div>

<p>And modify our <code class="language-plaintext highlighter-rouge">reports.rb</code> file to require the <code class="language-plaintext highlighter-rouge">generator</code>.</p>
<div class="language-ruby highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">require</span> <span class="s1">'reports/engine'</span>
<span class="nb">require</span> <span class="s1">'reports/generator'</span>
<span class="o">...</span>

</code></pre></div></div>

<p>Now, you can generate reports</p>
<div class="language-ruby highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="no">Reports</span><span class="o">::</span><span class="no">Generator</span><span class="p">.</span><span class="nf">run</span><span class="p">(</span><span class="ss">name: </span><span class="s1">'Sample Report'</span><span class="p">)</span>
</code></pre></div></div>

<h1 id="future-steps">Future Steps</h1>

<p>This post was written to introduce Component Based Architecture with Rails and walk you through creating your first engine. I encourage you to read more to learn about the benefits and drawbacks. Understanding both is important before adapting any architecture and using it in production applications.</p>

<p>I have used this technique with great success and believe many code bases would benefit from this modular monolith.</p>

<h1 id="useful-resources">Useful Resources</h1>

<p>If you are interested in learning more about applying Component Based Architecture to your Rails application then you might find some of the following links useful.</p>

<ul>
  <li><a href="https://guides.rubyonrails.org/engines.html" target="_blank">Rails Guide - Getting Started with Engines</a></li>
  <li><a href="https://www.cbra.info/" target="_blank">Book - Component-Based Rails by Stephan Hagemann</a></li>
  <li><a href="https://medium.com/@dan_manges/the-modular-monolith-rails-architecture-fb1023826fc4" target="_blank">Blog Post - The Modular Monolith: Rails Architecture by Dan Manges</a></li>
  <li><a href="https://www.youtube.com/watch?v=MsRPxS7Cu_Q" target="_blank">Talk - Get started with Component-based Rails applications! by Stephan Hagemann, 2015</a></li>
  <li><a href="https://github.com/taskrabbit/rails_engines_example" target="_blank">Sample Application - Rails engines example by Task Rabbit</a></li>
</ul>

<p> </p>
<h4 id="did-you-like-this-article-check-out-these-too">Did you like this article? Check out these too.</h4>

<ul>
  <li><a href="/blog/testing-an-engine-with-rspec/">How to add Rspec to a rails engine</a></li>
  <li><a href="/blog/rails-5-bunny-setup/">Rails 5 RabbitMQ Bunny Setup</a></li>
</ul>

<hr />

<p> </p>

<p>Found this useful? Have a suggestion? Get in touch at <code class="language-plaintext highlighter-rouge">blog@hocnest.com</code>.</p>]]></content><author><name>David Amrani</name></author><category term="rails" /><category term="architecture" /><category term="engines" /><summary type="html"><![CDATA[Create a local rails engine nested within your rails application following a component based architecture.]]></summary><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://www.hocnest.com/img/avatar@2x.png" /><media:content medium="image" url="https://www.hocnest.com/img/avatar@2x.png" xmlns:media="http://search.yahoo.com/mrss/" /></entry><entry><title type="html">Largest Prime Factor</title><link href="https://www.hocnest.com/blog/largest-prime-factor/" rel="alternate" type="text/html" title="Largest Prime Factor" /><published>2019-06-10T07:23:00-04:00</published><updated>2019-06-10T07:23:00-04:00</updated><id>https://www.hocnest.com/blog/largest-prime-factor</id><content type="html" xml:base="https://www.hocnest.com/blog/largest-prime-factor/"><![CDATA[<h1 id="what-is-project-euler">What is Project Euler</h1>
<p>Project Euler is a website with a collection of programming and mathematical problems. Each challenge varies in difficulty and there are over 600 challenges. I highly recommend anyone interested in puzzles and programming to create an account and start solving. <a href="https://projecteuler.net/about" target="_blank">About Project Euler</a></p>

<p>** Stop here if you have not yet tried and solved <a href="https://projecteuler.net/problem=3" target="_blank">Problem 3</a>. **</p>

<p>**</p>

<p>**</p>

<p>**</p>

<p>**</p>

<h1 id="problem-3">Problem 3</h1>

<p>The prime factors of 13195 are 5, 7, 13 and 29.</p>

<p>What is the largest prime factor of the number 600851475143 ?</p>

<div class="language-ruby highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">class</span> <span class="nc">Problem3</span>
  <span class="nb">require</span> <span class="s1">'benchmark'</span>

  <span class="k">def</span> <span class="nf">question</span>
    <span class="s2">"The prime factors of 13195 are 5, 7, 13 and 29.

    What is the largest prime factor of the number 600851475143 ?"</span>
  <span class="k">end</span>

  <span class="k">def</span> <span class="nf">largest_prime_factor</span> <span class="n">n</span>
    <span class="n">max</span> <span class="o">=</span> <span class="mi">0</span>
    <span class="n">limit</span> <span class="o">=</span> <span class="n">n</span>
    <span class="n">runner</span> <span class="o">=</span> <span class="mi">2</span>

    <span class="k">while</span><span class="p">(</span><span class="n">runner</span> <span class="o">&lt;=</span> <span class="n">limit</span><span class="p">)</span> <span class="k">do</span>
      <span class="n">factor</span> <span class="o">=</span> <span class="mi">0</span>
      <span class="k">if</span> <span class="n">limit</span> <span class="o">%</span> <span class="n">runner</span> <span class="o">==</span> <span class="mi">0</span>
        <span class="n">limit</span> <span class="o">=</span> <span class="n">limit</span> <span class="o">/</span> <span class="n">runner</span>
        <span class="n">factor</span> <span class="o">=</span> <span class="n">runner</span>
        <span class="n">max</span> <span class="o">=</span> <span class="n">factor</span> <span class="k">if</span> <span class="n">factor</span> <span class="o">&gt;</span> <span class="n">max</span>
      <span class="k">else</span>
        <span class="n">runner</span> <span class="o">=</span> <span class="n">runner</span> <span class="o">+</span> <span class="mi">1</span>
      <span class="k">end</span>
    <span class="k">end</span>

    <span class="n">max</span>
  <span class="k">end</span>

  <span class="k">def</span> <span class="nf">solve</span>
    <span class="n">largest_prime_factor</span><span class="p">(</span><span class="mi">600851475143</span><span class="p">)</span>
  <span class="k">end</span>

  <span class="k">def</span> <span class="nf">benchmark</span>
    <span class="no">Benchmark</span><span class="p">.</span><span class="nf">measure</span> <span class="p">{</span> <span class="n">solve</span> <span class="p">}</span>
  <span class="k">end</span>

  <span class="k">def</span> <span class="nf">correct?</span>
    <span class="n">solve</span> <span class="o">===</span> <span class="n">answer</span>
  <span class="k">end</span>

  <span class="kp">private</span>

  <span class="k">def</span> <span class="nf">answer</span>
    <span class="mi">6857</span>
  <span class="k">end</span>
<span class="k">end</span>
</code></pre></div></div>

<p> </p>
<h4 id="did-you-like-this-article-check-out-these-too">Did you like this article? Check out these too.</h4>
<ul>
  <li><a href="/blog/largest-palindrome-product/">Largest Palindrome Product</a></li>
  <li><a href="/blog/sum-of-even-fibonacci-numbers/">Sum of Even Fibonacci Numbers</a></li>
  <li><a href="/blog/project-euler-problem-1-in-ruby/">Project Euler Problem 1 in Ruby</a></li>
</ul>

<hr />

<p> </p>

<p>Found this useful? Have a suggestion? Get in touch at <code class="language-plaintext highlighter-rouge">blog@hocnest.com</code>.</p>]]></content><author><name>Dan Mave</name></author><category term="Project-Euler" /><category term="Ruby" /><summary type="html"><![CDATA[Determine the largest prime factor of the number 600851475143 in Ruby.]]></summary><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://www.hocnest.com/img/avatar@2x.png" /><media:content medium="image" url="https://www.hocnest.com/img/avatar@2x.png" xmlns:media="http://search.yahoo.com/mrss/" /></entry><entry><title type="html">Largest Palindrome Product</title><link href="https://www.hocnest.com/blog/largest-palindrome-product/" rel="alternate" type="text/html" title="Largest Palindrome Product" /><published>2019-06-07T07:14:00-04:00</published><updated>2019-06-07T07:14:00-04:00</updated><id>https://www.hocnest.com/blog/largest-palindrome-product</id><content type="html" xml:base="https://www.hocnest.com/blog/largest-palindrome-product/"><![CDATA[<h1 id="what-is-project-euler">What is Project Euler</h1>
<p>Project Euler is a website with a collection of programming and mathematical problems. Each challenge varies in difficulty and there are over 600 challenges. I highly recommend anyone interested in puzzles and programming to create an account and start solving. <a href="https://projecteuler.net/about" target="_blank">About Project Euler</a></p>

<p>** Stop here if you have not yet tried and solved <a href="https://projecteuler.net/problem=4" target="_blank">Problem 4</a>. **</p>

<p>**</p>

<p>**</p>

<p>**</p>

<p>**</p>

<h1 id="problem-4">Problem 4</h1>

<p>A palindromic number reads the same both ways. The largest palindrome made from the product of two 2-digit numbers is 9009 = 91 × 99.</p>

<p>Find the largest palindrome made from the product of two 3-digit numbers.</p>

<div class="language-ruby highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">class</span> <span class="nc">Problem4</span>
  <span class="nb">require</span> <span class="s1">'benchmark'</span>

  <span class="k">def</span> <span class="nf">question</span>
    <span class="s2">"A palindromic number reads the same both ways. The largest palindrome made from the product of two 2-digit numbers is 9009 = 91 × 99.

    Find the largest palindrome made from the product of two 3-digit numbers."</span>
  <span class="k">end</span>

  <span class="k">def</span> <span class="nf">select_largest_palindrome</span><span class="p">(</span><span class="n">list</span> <span class="o">=</span> <span class="p">[])</span>
    <span class="n">list</span> <span class="o">=</span> <span class="n">list</span><span class="p">.</span><span class="nf">sort</span>
    <span class="n">max</span> <span class="o">=</span> <span class="kp">nil</span>

    <span class="k">while</span><span class="p">(</span><span class="n">max</span><span class="p">.</span><span class="nf">nil?</span> <span class="o">&amp;&amp;</span> <span class="o">!</span><span class="n">list</span><span class="p">.</span><span class="nf">empty?</span><span class="p">)</span> <span class="k">do</span>
      <span class="n">n</span> <span class="o">=</span> <span class="n">list</span><span class="p">.</span><span class="nf">pop</span>
      <span class="n">max</span> <span class="o">=</span> <span class="n">n</span> <span class="k">if</span> <span class="n">n</span><span class="p">.</span><span class="nf">to_s</span> <span class="o">==</span> <span class="n">n</span><span class="p">.</span><span class="nf">to_s</span><span class="p">.</span><span class="nf">reverse</span>
    <span class="k">end</span>

    <span class="n">max</span>
  <span class="k">end</span>

  <span class="k">def</span> <span class="nf">find_largest_palindrome_product</span>
    <span class="n">pairs</span> <span class="o">=</span> <span class="p">(</span><span class="mi">100</span><span class="o">..</span><span class="mi">999</span><span class="p">).</span><span class="nf">to_a</span><span class="p">.</span><span class="nf">product</span><span class="p">((</span><span class="mi">100</span><span class="o">..</span><span class="mi">999</span><span class="p">).</span><span class="nf">to_a</span><span class="p">)</span>
    <span class="n">products</span> <span class="o">=</span> <span class="n">pairs</span><span class="p">.</span><span class="nf">map</span> <span class="p">{</span> <span class="o">|</span><span class="n">pair</span><span class="o">|</span> <span class="n">pair</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="o">*</span> <span class="n">pair</span><span class="p">[</span><span class="mi">1</span><span class="p">]</span> <span class="p">}</span>

    <span class="n">select_largest_palindrome</span><span class="p">(</span><span class="n">products</span><span class="p">)</span>
  <span class="k">end</span>

  <span class="k">def</span> <span class="nf">solve</span>
    <span class="n">find_largest_palindrome_product</span>
  <span class="k">end</span>

  <span class="k">def</span> <span class="nf">benchmark</span>
    <span class="no">Benchmark</span><span class="p">.</span><span class="nf">measure</span> <span class="p">{</span> <span class="n">solve</span> <span class="p">}</span>
  <span class="k">end</span>

  <span class="k">def</span> <span class="nf">correct?</span>
    <span class="n">solve</span> <span class="o">===</span> <span class="n">answer</span>
  <span class="k">end</span>

  <span class="kp">private</span>

  <span class="k">def</span> <span class="nf">answer</span>
    <span class="mi">906609</span>
  <span class="k">end</span>
<span class="k">end</span>
</code></pre></div></div>

<p> </p>
<h4 id="did-you-like-this-article-check-out-these-too">Did you like this article? Check out these too.</h4>
<ul>
  <li><a href="/blog/sum-of-even-fibonacci-numbers/">Sum of Even Fibonacci Numbers</a></li>
  <li><a href="/blog/project-euler-problem-1-in-ruby/">Project Euler Problem 1 in Ruby</a></li>
  <li><a href="/blog/largest-prime-factor/">Largest Prime Factor</a></li>
</ul>

<hr />

<p> </p>

<p>Found this useful? Have a suggestion? Get in touch at <code class="language-plaintext highlighter-rouge">blog@hocnest.com</code>.</p>]]></content><author><name>Dan Mave</name></author><category term="Project-Euler" /><category term="Ruby" /><summary type="html"><![CDATA[Find the largest palindrome made from the product of two 3-digit numbers in Ruby.]]></summary><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://www.hocnest.com/img/avatar@2x.png" /><media:content medium="image" url="https://www.hocnest.com/img/avatar@2x.png" xmlns:media="http://search.yahoo.com/mrss/" /></entry><entry><title type="html">Sum of Even Fibonacci Numbers</title><link href="https://www.hocnest.com/blog/sum-of-even-fibonacci-numbers/" rel="alternate" type="text/html" title="Sum of Even Fibonacci Numbers" /><published>2019-06-05T08:20:00-04:00</published><updated>2019-06-05T08:20:00-04:00</updated><id>https://www.hocnest.com/blog/sum-of-even-fibonacci-numbers</id><content type="html" xml:base="https://www.hocnest.com/blog/sum-of-even-fibonacci-numbers/"><![CDATA[<h1 id="what-is-project-euler">What is Project Euler</h1>
<p>Project Euler is a website with a collection of programming and mathematical problems. Each challenge varies in difficulty and there are over 600 challenges. I highly recommend anyone interested in puzzles and programming to create an account and start solving. <a href="https://projecteuler.net/about" target="_blank">About Project Euler</a></p>

<p>** Stop here if you have not yet tried and solved <a href="https://projecteuler.net/problem=2" target="_blank">Problem 2</a>. **</p>

<p>**</p>

<p>**</p>

<p>**</p>

<p>**</p>

<h1 id="problem-2">Problem 2</h1>

<p>Each new term in the Fibonacci sequence is generated by adding the previous two terms. By starting with 1 and 2, the first 10 terms will be:</p>

<p>1, 2, 3, 5, 8, 13, 21, 34, 55, 89, …</p>

<p>By considering the terms in the Fibonacci sequence whose values do not exceed four million, find the sum of the even-valued terms.</p>

<div class="language-ruby highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">class</span> <span class="nc">Problem2</span>
  <span class="nb">require</span> <span class="s1">'benchmark'</span>

  <span class="k">def</span> <span class="nf">question</span>
    <span class="s2">"Each new term in the Fibonacci sequence is generated by adding the previous two terms. By starting with 1 and 2, the first 10 terms will be:

    1, 2, 3, 5, 8, 13, 21, 34, 55, 89, ...

    By considering the terms in the Fibonacci sequence whose values do not exceed four million, find the sum of the even-valued terms."</span>
  <span class="k">end</span>


  <span class="k">def</span> <span class="nf">fibonacci_even_sum</span><span class="p">(</span><span class="n">limit</span> <span class="o">=</span> <span class="mi">4000000</span><span class="p">)</span>
    <span class="n">sum</span> <span class="o">=</span> <span class="mi">2</span>
    <span class="n">runner</span> <span class="o">=</span> <span class="mi">2</span>
    <span class="n">one_back</span> <span class="o">=</span> <span class="mi">1</span>
    <span class="n">two_back</span> <span class="o">=</span> <span class="mi">0</span>

    <span class="k">while</span><span class="p">(</span><span class="n">runner</span> <span class="o">&lt;=</span> <span class="n">limit</span><span class="p">)</span>
      <span class="n">sum</span> <span class="o">+=</span> <span class="n">runner</span> <span class="k">if</span> <span class="n">runner</span><span class="p">.</span><span class="nf">even?</span>

      <span class="n">two_back</span> <span class="o">=</span> <span class="n">one_back</span>
      <span class="n">one_back</span> <span class="o">=</span> <span class="n">runner</span>
      <span class="n">runner</span> <span class="o">=</span> <span class="n">two_back</span> <span class="o">+</span> <span class="n">one_back</span>
    <span class="k">end</span>

    <span class="n">sum</span>
  <span class="k">end</span>

  <span class="k">def</span> <span class="nf">solve</span>
    <span class="n">fibonacci_even_sum</span>
  <span class="k">end</span>

  <span class="k">def</span> <span class="nf">benchmark</span>
    <span class="no">Benchmark</span><span class="p">.</span><span class="nf">measure</span> <span class="p">{</span> <span class="n">solve</span> <span class="p">}</span>
  <span class="k">end</span>

  <span class="k">def</span> <span class="nf">correct?</span>
    <span class="n">solve</span> <span class="o">===</span> <span class="n">answer</span>
  <span class="k">end</span>

  <span class="kp">private</span>

  <span class="k">def</span> <span class="nf">answer</span>
    <span class="mi">4613732</span>
  <span class="k">end</span>
<span class="k">end</span>
</code></pre></div></div>

<p> </p>
<h4 id="did-you-like-this-article-check-out-these-too">Did you like this article? Check out these too.</h4>
<ul>
  <li><a href="/blog/largest-palindrome-product/">Largest Palindrome Product</a></li>
  <li><a href="/blog/project-euler-problem-1-in-ruby/">Project Euler Problem 1 in Ruby</a></li>
  <li><a href="/blog/largest-prime-factor/">Largest Prime Factor</a></li>
</ul>

<hr />

<p> </p>

<p>Found this useful? Have a suggestion? Get in touch at <code class="language-plaintext highlighter-rouge">blog@hocnest.com</code>.</p>]]></content><author><name>Dan Mave</name></author><category term="Project-Euler" /><category term="Ruby" /><summary type="html"><![CDATA[Find the sum of the even-valued terms in the Fibonacci sequence whose values do not exceed four million in Ruby.]]></summary><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://www.hocnest.com/img/avatar@2x.png" /><media:content medium="image" url="https://www.hocnest.com/img/avatar@2x.png" xmlns:media="http://search.yahoo.com/mrss/" /></entry></feed>