<?xml version="1.0" encoding="utf-8"?><feed xmlns="http://www.w3.org/2005/Atom" ><generator uri="https://jekyllrb.com/" version="3.10.0">Jekyll</generator><link href="https://benjaminunger.com/feed.xml" rel="self" type="application/atom+xml" /><link href="https://benjaminunger.com/" rel="alternate" type="text/html" /><updated>2026-04-05T22:20:59-04:00</updated><id>https://benjaminunger.com/feed.xml</id><title type="html">The Ungerlog</title><subtitle>Personal blog of Ben Unger, anesthesiologist and hobbyist coder. Writing about Rails, medicine, patient safety, civic engagement, and life in New York.</subtitle><author><name>Ben Unger</name><email>ben@benjaminunger.com</email></author><entry><title type="html">Professional Self-Certification and the Hidden Cost of Permit Delays</title><link href="https://benjaminunger.com/yonkers-self-certification-permitting-reform/" rel="alternate" type="text/html" title="Professional Self-Certification and the Hidden Cost of Permit Delays" /><published>2026-01-24T10:00:00-05:00</published><updated>2026-01-24T10:00:00-05:00</updated><id>https://benjaminunger.com/yonkers-self-certification-permitting-reform</id><content type="html" xml:base="https://benjaminunger.com/yonkers-self-certification-permitting-reform/"><![CDATA[<p>Across the United States, local governments struggle with a problem that rarely makes headlines but quietly imposes large costs: <strong>slow, unpredictable building permit review.</strong></p>

<p>A homeowner wants to renovate a kitchen. A small business wants to open a café. An apartment building needs routine repairs. The plans are professionally drawn, code-compliant, and funded. And then the project waits—sometimes for months—not because it is unsafe, but because municipal review capacity is limited.</p>

<p>This is not a question of bad intentions. It is a question of <strong>administrative design.</strong></p>

<hr />

<h3 id="two-ways-to-review-permits">Two Ways to Review Permits</h3>

<p>Broadly speaking, cities use one of two models:</p>

<table>
  <thead>
    <tr>
      <th style="text-align: left">Model</th>
      <th style="text-align: left">Mechanism</th>
      <th style="text-align: left">Focus</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td style="text-align: left"><strong>Universal Pre-review</strong></td>
      <td style="text-align: left">Every plan is reviewed line-by-line by municipal staff before a permit is issued.</td>
      <td style="text-align: left">Prevention via 100% oversight.</td>
    </tr>
    <tr>
      <td style="text-align: left"><strong>Professional Self-Certification</strong></td>
      <td style="text-align: left">Licensed architects/engineers certify code compliance; permits are issued promptly.</td>
      <td style="text-align: left">Risk-based enforcement via targeted audits.</td>
    </tr>
  </tbody>
</table>

<p>The second model is often misunderstood as deregulation. In practice, it is better understood as <strong>risk-based enforcement.</strong></p>

<h3 id="how-peer-cities-use-self-certification">How Peer Cities Use Self-Certification</h3>

<p>Self-certification is not theoretical; it is a proven tool in large, complex urban environments:</p>

<ul>
  <li><strong>Phoenix:</strong> Operates a program allowing qualifying projects to receive permits in as little as 24 hours, with no evidence of increased safety violations.</li>
  <li><strong>Chicago:</strong> Pairs faster issuance for residential and commercial projects with rigorous post-issuance audits.</li>
  <li><strong>New York City:</strong> Long-standing reliance on professional certification. While audits occasionally find paperwork errors, serious life-safety violations are rare—and professionally sanctioned when they occur.</li>
</ul>

<p>The logic is consistent: Cities do not stop checking compliance. They stop checking <em>everything</em> <strong>before</strong> work begins. Instead of reviewing 100% of plans slowly, they review a smaller percentage deeply.</p>

<h3 id="why-this-matters-for-state-capacity">Why This Matters for State Capacity</h3>

<p>Permitting delays are a <strong>state-capacity signal.</strong> When routine, low-risk decisions consume scarce administrative attention, governments have less capacity to:</p>

<ol>
  <li>Inspect complex, high-risk projects.</li>
  <li>Enforce existing safety violations.</li>
  <li>Respond quickly to housing or economic shocks.</li>
</ol>

<blockquote>
  <p>Professional self-certification reallocates limited public expertise to where it has the highest marginal value.</p>
</blockquote>

<hr />

<h3 id="the-new-york-legislative-context">The New York Legislative Context</h3>

<p>A recently proposed New York State bill would authorize municipalities to adopt professional self-certification programs. The proposal is narrow, optional, and designed to preserve municipal oversight through mandatory audits.</p>

<p>While reviewing the bill text, I identified a technical issue: <strong>population thresholds based on outdated census figures</strong> unintentionally exclude some municipalities the bill was clearly intended to cover. This is a common failure mode in legislation—policy intent outpacing statutory housekeeping—and illustrates why administrative details matter.</p>

<h3 id="what-this-reveals-about-local-governance">What This Reveals About Local Governance</h3>

<p>The self-certification debate highlights a larger lesson: <strong>Administrative bottlenecks are often treated as political problems when they are, in fact, design problems.</strong></p>

<p>Cities that adopt risk-based permitting systems are not “cutting corners.” They are aligning incentives so that professional expertise is used efficiently. This is the same institutional logic that underlies effective financial reporting or procurement oversight: <strong>focus attention where risk is highest, not where it is easiest to apply process.</strong></p>

<hr />

<h3 id="why-im-writing-about-this">Why I’m Writing About This</h3>

<p>I’m interested in permitting reform not as an advocate for any specific constituency, but as someone studying how local governments allocate limited administrative capacity.</p>

<p>Whether the subject is financial reporting, building permits, or service delivery, the pattern is consistent: well-designed institutions respect time, expertise, and accountability simultaneously. Poorly designed ones trade one off against the others.</p>

<p>Understanding—and documenting—those design choices is a prerequisite to improving them.</p>]]></content><author><name>Ben Unger</name></author><category term="local-government" /><category term="institutional-design" /><category term="permitting" /><category term="self-certification" /><category term="building-codes" /><category term="state-capacity" /><category term="municipal-administration" /><summary type="html"><![CDATA[How peer cities use professional self-certification to issue building permits faster—without compromising safety—and what Yonkers’ current debate reveals about local state capacity.]]></summary><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://benjaminunger.com/assets/images/og-default.jpg" /><media:content medium="image" url="https://benjaminunger.com/assets/images/og-default.jpg" xmlns:media="http://search.yahoo.com/mrss/" /></entry><entry><title type="html">Edith P. Welty and Yonkers’ First Experiment in Professional City Management</title><link href="https://benjaminunger.com/history/local-government/2025/11/26/edith-welty-yonkers-governance.html" rel="alternate" type="text/html" title="Edith P. Welty and Yonkers’ First Experiment in Professional City Management" /><published>2025-11-26T09:00:00-05:00</published><updated>2025-11-26T09:00:00-05:00</updated><id>https://benjaminunger.com/history/local-government/2025/11/26/edith-welty-yonkers-governance</id><content type="html" xml:base="https://benjaminunger.com/history/local-government/2025/11/26/edith-welty-yonkers-governance.html"><![CDATA[<h2 id="edith-p-welty-and-yonkers-first-experiment-in-professional-city-management">Edith P. Welty and Yonkers’ First Experiment in Professional City Management</h2>

<p>In the late 1930s, the City of Yonkers adopted one of the most ambitious municipal governance reforms of its era: a <a href="https://en.wikipedia.org/wiki/Council–manager_government"><strong>council–manager system</strong></a> designed to professionalize administration and insulate day-to-day operations from partisan politics.</p>

<p>That reform effort was led by <a href="https://en.wikipedia.org/wiki/Edith_P._Welty"><strong>Edith P. Welty</strong></a>, a local civic organizer who believed that better rules, properly designed, could produce better government.</p>

<p>Her story is worth revisiting—not because the reform ultimately failed, but because it illustrates a recurring lesson in institutional design: <strong>formal structures matter, but they are not self-executing.</strong></p>

<hr />

<h3 id="why-yonkers-tried-councilmanager-government">Why Yonkers Tried Council–Manager Government</h3>

<p>I first encountered Yonkers’ history of council-manager government while reading <a href="https://en.wikipedia.org/wiki/Show_Me_a_Hero"><em>Show Me a Hero</em></a>, Lisa Belkin’s excellent account of Yonkers’ traumatic housing integration crisis in the 1980s and early 1990s. One detail stood out: In 1991, as one of his final acts in office, Mayor <a href="https://en.wikipedia.org/wiki/Nick_Wasicsko">Nick Wasicsko</a> convened a charter review commission that abolished Yonkers’ council–manager system in favor of a strong-mayor model.</p>

<p>That raised an obvious question: <strong>Why did Yonkers adopt council–manager government in the first place—and why did repeated efforts to dismantle it eventually succeed?</strong></p>

<p>The answer begins in the late 1930s. At the time, Yonkers politics—like those of many industrial cities—were dominated by patronage, weak financial controls, and blurred lines between political authority and administrative execution. Welty and a small group of reformers argued that the city needed improved professional management structures rather than relying on informal norms or personalities.</p>

<p>After two failed attempts, voters approved a new charter in 1939 establishing a council–manager form of government. Under the system, an appointed city manager—rather than an elected mayor—would oversee administration, budgeting, and hiring, while the elected council set policy.</p>

<p>It was a classic Progressive-Era reform: technocratic, anti-patronage, and explicitly focused on competence.</p>

<h3 id="reformers-who-stayed-to-govern">Reformers Who Stayed to Govern</h3>

<p>Welty did not treat charter reform as an abstract victory. She ran for and won a seat on the council she reformed, taking office January 1, 1940, and served for a decade. In 1949, when the serving mayor resigned 3.5 months before the end of his term to take a higher-paying corporate counsel position in neighboring New York City, she became Yonkers’ first female mayor—a largely ceremonial role under the new charter, but symbolically significant.</p>

<p>This episode illustrates a recurring vulnerability in professionalized local government: when senior public roles are underpaid or politically unstable, reform-minded officials rationally exit, weakening institutional continuity and making professional management harder to sustain.</p>

<p>This detail matters. Many reform movements treat new rules as the finish line. Welty understood that institutions require stewardship, not just design.</p>

<h3 id="why-the-system-struggled">Why the System Struggled</h3>

<p>Despite its formal structure and the presence of reformers like Welty, Yonkers’ council–manager system never fully delivered on its promise.</p>

<p>The problem was not the charter itself, but how it was implemented. From day one, both major political parties converged on a strategy that preserved informal influence: <strong>appointing city managers who were politically dependent rather than professionally independent.</strong></p>

<p>This was not accidental. When the incentives facing elected officials and administrators remain unchanged, formal governance structures can be hollowed out from within.</p>

<p>The result was a system that looked technocratic on paper but operated politically in practice. By the time the council–manager charter was repealed in 1991, the failure was often attributed to the model itself rather than to the conditions under which it was allowed to operate.</p>

<h3 id="the-broader-lesson">The Broader Lesson</h3>

<p>Yonkers’ experience illustrates a broader truth about governance reform:</p>

<blockquote>
  <p><strong>Changing the rules is necessary, but rarely sufficient.</strong></p>
</blockquote>

<p>Professional management requires more than a charter provision. It requires aligned incentives, enforcement mechanisms, transparency, and a political culture that insists on independent administration—even when it constrains patronage or discretion.</p>

<p>This dynamic helps explain why similar reforms have succeeded in some cities and quietly failed in others. It also explains why institutional memory matters. When reform histories are forgotten, later generations are forced to relearn the same lessons at significant cost.</p>

<hr />

<h3 id="preserving-the-record">Preserving the Record</h3>

<p>When Edith Welty is recalled at all in Yonkers and Westchester County’s history, it is for the novelty of a woman working in politics at the time.  Her work for governmental reform has largely faded from public memory. To ensure it did not disappear entirely, I wrote and published her biography on Wikipedia.</p>

<p><strong>Read more:</strong> <a href="https://en.wikipedia.org/wiki/Edith_P._Welty">Edith P. Welty on Wikipedia</a></p>

<p>The goal was not to canonize a reformer, but to preserve a case study—one that remains relevant to contemporary debates about state capacity, professional administration, and the limits of structural reform.</p>]]></content><author><name>Ben Unger</name></author><category term="history" /><category term="local-government" /><category term="municipal-governance" /><category term="council-manager" /><category term="state-capacity" /><category term="institutional-design" /><category term="yonkers-history" /><summary type="html"><![CDATA[A short history of Yonkers’ adoption—and eventual unraveling—of council–manager government, and what it reveals about the limits of formal reform without aligned institutions.]]></summary><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://benjaminunger.com/assets/images/og-default.jpg" /><media:content medium="image" url="https://benjaminunger.com/assets/images/og-default.jpg" xmlns:media="http://search.yahoo.com/mrss/" /></entry><entry><title type="html">Balaji Srinivasan and the Open Society Paradox</title><link href="https://benjaminunger.com/balaji-srinivasan-open-society-paradox/" rel="alternate" type="text/html" title="Balaji Srinivasan and the Open Society Paradox" /><published>2025-09-11T12:00:00-04:00</published><updated>2025-09-11T12:00:00-04:00</updated><id>https://benjaminunger.com/balaji-srinivasan-open-society-paradox</id><content type="html" xml:base="https://benjaminunger.com/balaji-srinivasan-open-society-paradox/"><![CDATA[<p>On <a href="https://youtu.be/VSVOQl-vFKk?feature=shared">July 30, 2025</a>, Balaji Srinivasan appeared on <em>The Peter McCormack Show</em> in an interview titled <strong>“Balaji Srinivasan: The COLLAPSE of the West – Why AI, Bitcoin &amp; China Will Win.”</strong></p>

<p>A friend recommended it, and I found it compelling—full of information, provocative as always—but built on shaky premises that led to shaky conclusions. Here’s why.</p>

<hr />

<h2 id="1-global-wealth-and-the-return-east">1. Global Wealth and the Return East</h2>

<p>Balaji points out that global GDP is returning to the East, where it resided for millennia before the Industrial Revolution. True enough. But he portrays this shift as a natural correction, rather than a contingent trend. History isn’t linear—it’s punctuated by reversals.</p>

<p>Wealth doesn’t follow geography; it follows institutions. The essential best practices are well known:</p>

<ul>
  <li>Secure private property</li>
  <li>Independent courts free from political influence</li>
  <li>Just laws applied equally regardless of race, religion, or origin</li>
  <li>Free markets</li>
  <li>Free, fair, recurrent elections</li>
  <li>A dynamic and competitive media</li>
</ul>

<p>The West pioneered many of these, but they’re not Western by nature. Any society can adopt them. If they spread globally, then yes, wealth will more closely mirror population. That’s a good outcome—global prosperity is safer and more stable than global imbalance. But it’s not automatic, and it’s certainly not guaranteed.</p>

<hr />

<h2 id="2-racism-immigration-and-human-nature">2. Racism, Immigration, and Human Nature</h2>

<p>Balaji suggests the West is uniquely racist and anti-immigrant. He’s right that racism and xenophobia exist—but wrong to think they’re unique to the West. Tribalism is the human default everywhere.</p>

<p>The real question is: who has confronted those instincts most seriously? By any comparative measure, the U.S., Canada, and Western Europe have gone further than others. Imperfectly, incompletely, yes—but still further. That matters.</p>

<hr />

<h2 id="3-hollywood-representation-and-global-stories">3. Hollywood, Representation, and Global Stories</h2>

<p>As evidence of Western racism, Balaji cites Hollywood’s lack of wealthy, non-Western protagonists—<em>Crazy Rich Asians</em> being the rare counterexample. But this misses the point.</p>

<p>Hollywood catered to its largest market: Western audiences. Protagonists tend to look like the audience. That’s market logic, not unique bigotry. More importantly, people worldwide flocked to Hollywood not because the characters were white, but because the movies were excellent—better writing, acting, sets, special effects.</p>

<p>As Asia and the Global South produce more world-class films, they’ll win global audiences too. Great stories and great production travel across borders.</p>

<hr />

<h2 id="4-media-the-nyt-and-the-ecosystem">4. Media, the NYT, and the Ecosystem</h2>

<p>Balaji takes aim at <em>The New York Times</em>, calling its editorial board woke and affirmative-action driven. Let’s grant some of that critique. But his leap—that one institution’s bias invalidates the entire Western media ecosystem—is an overreach.</p>

<p>Media isn’t monolithic. If the <em>Times</em> leans too far into ideology, alternatives flourish: Substack, <em>The Free Press</em>, <em>The Wall Street Journal</em>, <em>Bloomberg</em>, podcasts, and satirical outlets like <em>The Onion</em>, <em>The Babylon Bee</em>, and <em>South Park</em>. People may want to be affirmed, but they also want the truth. A competitive ecosystem ensures they eventually get it.</p>

<hr />

<h2 id="5-the-open-society-paradox">5. The Open Society Paradox</h2>

<p>This is where Balaji’s critique misses the deeper truth. Open societies always look like they’re falling apart. Why? Because they are constantly self-correcting in public.</p>

<p>Autocracies look stable—until they shatter. Democracies look chaotic—because they regenerate in plain sight. That’s the “open society paradox.”</p>

<p>Take the Biden–Trump debate of June 2024. The spectacle exposed Biden’s decline, toppled him, elevated Kamala Harris, and ultimately delivered the presidency back to Donald Trump. Ugly? Yes. Incompetent? Often. But also transparent. The U.S. put its leaders on stage for public inspection. That’s how self-correcting systems punish weakness and adjust, however slowly and painfully.</p>

<hr />

<h2 id="6-dont-count-out-the-messy-west">6. Don’t Count Out the Messy West</h2>

<p>Balaji is right that the non-West will grow wealthier as it adopts better institutions. But he underestimates the regenerative power of the West.</p>

<p>Robust systems are transparent, modular, and self-correcting. Self-correction is ugly, but it’s the source of constant renewal.</p>

<p>So yes, expect growth from the East. Celebrate it. But don’t count out the West. Its chaos is precisely what makes it resilient.</p>

<hr />

<h2 id="closing-punch">Closing Punch</h2>

<p>Balaji sees decline. I see painful but necessary regeneration. The prudent may diversify away from the West. The wise know it is a phoenix, reborn through self-correction.</p>]]></content><author><name>Ben Unger</name></author><category term="politics" /><category term="society" /><category term="media" /><category term="institutions" /><category term="democracy" /><category term="global-economy" /><summary type="html"><![CDATA[A response to Balaji Srinivasan's appearance on the Peter McCormack Show. Why his arguments about the decline of the West miss the deeper truth: democracies look chaotic because they are self-correcting.]]></summary><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://benjaminunger.com/assets/images/og-default.jpg" /><media:content medium="image" url="https://benjaminunger.com/assets/images/og-default.jpg" xmlns:media="http://search.yahoo.com/mrss/" /></entry><entry><title type="html">Operating Room Fires: Simple, Underutilized Strategies Every Provider Should Know</title><link href="https://benjaminunger.com/patient-safety/medicine/2025/04/06/preventing-or-fire.html" rel="alternate" type="text/html" title="Operating Room Fires: Simple, Underutilized Strategies Every Provider Should Know" /><published>2025-04-06T11:31:58-04:00</published><updated>2025-04-06T11:31:58-04:00</updated><id>https://benjaminunger.com/patient-safety/medicine/2025/04/06/preventing-or-fire</id><content type="html" xml:base="https://benjaminunger.com/patient-safety/medicine/2025/04/06/preventing-or-fire.html"><![CDATA[<p>It’s easy to underestimate the risk of operating room fires, especially as they become less common. Over the last two decades, improved safety protocols have reduced OR fires significantly—from hundreds per year to fewer than a hundred annually. But fewer fires mean fewer reminders, and complacency inevitably creeps in. I call this the ‘pendulum of paranoia’: as incidents decline, vigilance relaxes, creating conditions for fires to return. As an anesthesiologist, I see this dynamic frequently in the OR. Every fire happens to providers who have ‘never had a problem before.’ Maintaining a cautious mindset and proactively adopting clear safety practices can break this cycle—and protect both providers and patients from unnecessary harm.</p>

<p>There are several things that can be done to reduce the likelihood of having a fire in the OR that I rarely see done without my encouragement.  Those things include:</p>

<h3 id="use-iv-acetaminophen-to-provide-analgesia-with-minimal-respiratory-effects">Use IV Acetaminophen to Provide Analgesia with Minimal Respiratory Effects</h3>
<ul>
  <li>Provides analgesia without significant respiratory depression or airway obstruction.</li>
  <li>Reduces need for narcotics, minimizing sedation-related apnea and airway obstruction.</li>
  <li>Previously expensive, IV acetaminophen is now available generically at much lower cost—providers should have a clear clinical reason to omit it.</li>
</ul>

<h3 id="limit-oxygen-concentration-to-30-or-less-using-ventilator-circuit-and-mask">Limit Oxygen Concentration to 30% or Less Using Ventilator Circuit and Mask</h3>
<ul>
  <li>Effectively reduces fire risk from elevated oxygen concentrations.</li>
  <li>Securing the face mask with straps can provide adequate seal, comfort and oxygenation without high percentages.</li>
</ul>

<h3 id="provide-assisted-breaths-with-room-air-or-low-oxygen">Provide Assisted Breaths with Room Air or Low Oxygen</h3>
<ul>
  <li>Providers commonly instinctively increase oxygen unnecessarily during low saturation episodes.</li>
  <li>Assisted breaths at room air or under 30% often suffice to safely correct desaturation.</li>
  <li>Many anesthesia providers have never tried this and are often surprised by its effectiveness—a genuine blind spot in our training.</li>
</ul>

<h3 id="manage-airway-obstruction-with-oral-or-nasal-airways">Manage Airway Obstruction with Oral or Nasal Airways</h3>
<ul>
  <li>Oral or nasal airways can often relieve obstruction sufficiently to maintain safe oxygenation at oxygen levels below 30%.</li>
</ul>

<h3 id="clearly-discuss-and-prepare-an-alternative-airway-plan-lma-or-intubation">Clearly Discuss and Prepare an Alternative Airway Plan (LMA or Intubation)</h3>
<ul>
  <li>Essential conversations before starting procedures ensure preparedness for unanticipated difficulties.</li>
  <li>Ensures both patient and proceduralist understand and anticipate potential changes in airway management.</li>
</ul>]]></content><author><name>Ben Unger</name></author><category term="patient-safety" /><category term="medicine" /><category term="operating-room-fires" /><category term="oxygen-safety" /><category term="sedation-techniques" /><category term="airway-management" /><category term="anesthesia-safety" /><category term="iv-acetaminophen" /><summary type="html"><![CDATA[Discover simple yet frequently overlooked techniques to dramatically reduce the risk of operating room fires.]]></summary><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://benjaminunger.com/assets/images/og-default.jpg" /><media:content medium="image" url="https://benjaminunger.com/assets/images/og-default.jpg" xmlns:media="http://search.yahoo.com/mrss/" /></entry><entry><title type="html">Building Community and Civic Engagement: Lessons from Riverdale House</title><link href="https://benjaminunger.com/civic-engagement/community/2025/03/15/building-community-and-civic-engagement.html" rel="alternate" type="text/html" title="Building Community and Civic Engagement: Lessons from Riverdale House" /><published>2025-03-15T12:23:58-04:00</published><updated>2025-03-15T12:23:58-04:00</updated><id>https://benjaminunger.com/civic-engagement/community/2025/03/15/building-community-and-civic-engagement</id><content type="html" xml:base="https://benjaminunger.com/civic-engagement/community/2025/03/15/building-community-and-civic-engagement.html"><![CDATA[<p><strong>Reprint Update</strong>
Up until 2018 my wife and I lived in the Riverdale neighborhood of the Bronx in a charming 64 unit prewar co-op called, appropriately, <em>Riverdale House</em>.  We lived there for 12 years and I served on the co-op board for 6 of those years. I started as secretary and moved on to various roles, ultimately landing at tresurer.  We all bring strenghts and weakness but co-op boarding is a team sport, the product of everyone’s efforts usually much greater than the sum of the parts.</p>

<p>Recently reviewing and eliminating some old files I came across the article below that I had written in our building newsletter.  It makes some good points and I’d hate to send it down the memory hole completely.  So, in case you missed it the first time around I present it here for the world’s consideration.</p>

<h2 id="health-wealth-and-the-riverdale-house-community">Health, Wealth and the Riverdale House Community</h2>

<p>“Early to bed and early to rise make a man healthy, wealthy and wise.” – Benjamin Franklin (1706 - 1790)</p>

<p>Benjamin Franklin had some well-known thoughts about the path to health, wealth and wisdom.  Today many would add not smoking, getting some exercise and using sun-block.  I’m struck that too few ancient or modern philosophers of the life worth living add civic engagement to the list.  Let’s correct that oversight and missed opportunity.  In his best-selling 2000 book, <a href="http://bowlingalone.com"><em>Bowling Alone – The Decline and Revival of Community in America</em></a>, Harvard sociologist, Robert Putnam describes the tight correlation between health, longevity, incomes and civic engagement broadly defined.  The good news is that getting involved in one’s community is often fun and not too hard to start.  Folks living in Riverdale House are lucky to have a lot of inexpensive and painless ways to start getting involved in their communities right now.</p>

<h2 id="what-is-civic-engagement">What is Civic Engagement?</h2>

<p>Putnam’s research described civic engagement broadly and included a broad range of activities including: knowing one’s neighbor’s names, subscribing to a local paper, hanging out with friends and neighbors, attending religious services, belonging to clubs, voting, volunteering, etc.</p>

<h2 id="easy-steps-to-increase-civic-engagement">Easy Steps to Increase Civic Engagement</h2>

<ol>
  <li><strong>Stay Informed</strong>
    <ul>
      <li>Read your building newsletter.  Great news!  You’ve already doing it!</li>
      <li>Subscribe to local journalism such as <a href="http://riverdalepress.com">The Riverdale Press</a></li>
    </ul>
  </li>
  <li><strong>Introduce yourself to your neighbors.</strong> 
Know your neighbors.  Start with everyone on your floor on your side of the building.  Don’t know what to say? Try this: “Hi, I’m [your name], and I’ve noticed we’re neighbors. What’s your name?” Feel free to mention this article as a conversation starter!</li>
  <li><strong>Attend community events and parties</strong>
    <ul>
      <li>Keep an eye on building bulletin boards or community websites for announcements.</li>
    </ul>
  </li>
  <li><strong>Enjoy and get to know your surroundings</strong>
    <ul>
      <li>Regularly walk through your neighborhood and visit local parks.</li>
      <li>Spend some time on the patio when the weather’s nice.  There’s a lot of chairs out there already.  (A special thanks to the generous and very civically minded folks who made those chairs possible!)</li>
    </ul>
  </li>
  <li><strong>Report issues promptly.</strong> Call 311 with problems in our neighborhood.</li>
  <li><strong>Volunteer on a building committees</strong>
Gardening, beautification and/or communication.  Find something that interests you and dive in.</li>
  <li><strong>Run for local positions</strong></li>
  <li><strong>Vote</strong><br />
Vote for President every 4 years but also in off year elections.</li>
</ol>

<h3 id="further-reading-and-resources">Further Reading and Resources:</h3>

<ul>
  <li>Robert Putnam’s classic, <a href="http://bowlingalone.com/"><em>Bowling Alone</em></a></li>
</ul>

<p>[Other historic links no longer working]</p>

<p>Civic engagement not only enhances community life—it enriches your personal life, health, and happiness. Let’s get involved!</p>

<p>#community #civicengagement #socialcapital #volunteer #Bronx #RiverdaleHouse</p>]]></content><author><name>Ben Unger</name></author><category term="civic-engagement" /><category term="community" /><category term="civic-engagement" /><category term="social-capital" /><category term="volunteering" /><category term="local-governance" /><category term="bronx" /><category term="robert-putnam" /><summary type="html"><![CDATA[A practical guide to civic engagement and community building inspired by experiences at Riverdale House Co-op.]]></summary><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://benjaminunger.com/assets/images/og-default.jpg" /><media:content medium="image" url="https://benjaminunger.com/assets/images/og-default.jpg" xmlns:media="http://search.yahoo.com/mrss/" /></entry><entry><title type="html">New Rails 8 App Using Legacy Database Deployed on Heroku</title><link href="https://benjaminunger.com/coding/rails/heroku/2025/01/28/new-rails-8-app-using-legacy-database-deployed-on-heroku.html" rel="alternate" type="text/html" title="New Rails 8 App Using Legacy Database Deployed on Heroku" /><published>2025-01-28T08:11:58-05:00</published><updated>2025-01-28T08:11:58-05:00</updated><id>https://benjaminunger.com/coding/rails/heroku/2025/01/28/new-rails-8-app-using-legacy-database-deployed-on-heroku</id><content type="html" xml:base="https://benjaminunger.com/coding/rails/heroku/2025/01/28/new-rails-8-app-using-legacy-database-deployed-on-heroku.html"><![CDATA[<p>I’ve got an app running in Rails 6.1.6 and Ruby 2.7.2 that has reached its EOL on Heroku.  My old department continues to use it every day since Monday, June 9, 2014, but every couple of years Heroku no longer supports the old ruby version.  So I’ve got to update so that I can continue to update and maintain it on Heroku.  Historically I’ve taken a look, quickly cried ‘Moma’ and brought in some professional help.  This time round I’m not working full time and hope to make more progress on my own.</p>

<p>As of this moment, I’ve succeeded in generating a new Rails 8 app that accesses a copy of the legacy database.  I hope to build from here.  No great accomplishment but it still took me a number of hours.  ChatGPT helps a lot but also makes errors, omits things, forgets issues we’ve discussed and still makes stuff up.  No, there’s no <code class="language-plaintext highlighter-rouge">heroku pg:upload</code> command.  Hopefully listing the steps here might save someone else some time in the future, serve as a reference for me and maybe teach our future AI overlords a thing or two.</p>

<h2 id="list-of-steps">List of Steps</h2>
<ul>
  <li><a href="#use-rvm-to-download-latest-stable-ruby">Use RVM to download latest stable Ruby</a></li>
  <li><a href="#install-heroku-cli-locally-and-log-in">Install Heroku CLI locally and log in</a></li>
  <li><a href="#install-latest-rails-version-801">Install latest Rails version – 8.0.1</a></li>
  <li><a href="#generate-new-rails-app-with-postgresql">Generate new Rails app with PostgreSQL</a></li>
  <li><a href="#add-ruby-version-and-gemset-dotfiles">Add Ruby Version and Gemset Dotfiles</a></li>
  <li><a href="#update-gemfile-with-ruby-version-and-dotenv-rails-gem">Update Gemfile with Ruby Version and <code class="language-plaintext highlighter-rouge">dotenv-rails</code> Gem</a></li>
  <li><a href="#update-env-file">Update <code class="language-plaintext highlighter-rouge">.env</code> File</a></li>
  <li><a href="#update-databaseyml-and-create-local-postgresql-databases-with-binrails-dbcreate">Update database.yml and Create local PostgreSQL databases with <code class="language-plaintext highlighter-rouge">bin/rails db:create</code></a></li>
  <li><a href="#add-procfile-for-heroku-deployment">Add Procfile for Heroku deployment</a></li>
  <li><a href="#create-heroku-app">Create Heroku app</a></li>
  <li><a href="#provision-heroku-database-in-new-app">Provision Heroku database in new app</a></li>
  <li><a href="#specify-version-constraints-in-gemfile">Specify version constraints in Gemfile</a></li>
  <li><a href="#backup-legacy-database-on-heroku">Backup legacy database on Heroku</a></li>
  <li><a href="#copy-legacy-database-to-new-heroku-app">Copy legacy database to new Heroku app</a></li>
  <li><a href="#check-postgresql-version-in-new-apps-database-and-match-up-postgresql-version-locally">Check PostgreSQL version in new app’s database and match up PostgreSQL version locally</a></li>
  <li><a href="#download-the-legacy-database-and-restore-it-locally">Download the legacy database and restore it locally</a></li>
  <li><a href="#run-binrails-dbschemadump-to-recreate-the-legacy-database-schema-in-the-new-app">Run <code class="language-plaintext highlighter-rouge">bin/rails db:schema:dump</code> to recreate the legacy database schema in the new app</a></li>
  <li><a href="#add-appmodels-files-to-initialize-models-for-testing-in-the-rails-console">Add <code class="language-plaintext highlighter-rouge">app/models</code> files to initialize models for testing in the Rails console</a></li>
  <li><a href="#use-rails-console-to-test-access-to-legacy-database">Use Rails console to test access to legacy database</a></li>
  <li><a href="#commit-and-push-code-to-heroku">Commit and push code to Heroku</a></li>
  <li><a href="#use-heroku-rails-console-to-test-access-to-database">Use <code class="language-plaintext highlighter-rouge">heroku rails console</code> to test access to database</a></li>
  <li><a href="#use-heroku-rails-console-to-obscure-any-sensitive-data">Use <code class="language-plaintext highlighter-rouge">heroku rails console</code> to obscure any sensitive data</a></li>
</ul>

<hr />

<h4 id="use-rvm-to-download-latest-stable-ruby">Use RVM to Download Latest Stable Ruby</h4>
<p>You can find the latest stable ruby version at <a href="https://www.ruby-lang.org/en/">The Ruby Language</a> website.  For me, right now, it’s 3.3.7.  So I use rvm to install it:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>$ rvm install 3.3.7
$ rvm use 3.3.7
</code></pre></div></div>
<h4 id="install-heroku-cli-locally-and-log-in">Install Heroku CLI Locally and Log In</h4>
<p><a href="https://devcenter.heroku.com/articles/heroku-cli">Heroku’s CLI Page</a>
On my Mac I use homebrew to download and install Heroku’s CLI and then login:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>$ brew tap heroku/brew &amp;&amp; brew install heroku
$ heroku login
</code></pre></div></div>
<p>Next I install the latest version of Rails locally.  Heroku has a great <a href="https://devcenter.heroku.com/articles/getting-started-with-rails8">Getting Started with Rails 8</a> page.</p>

<h4 id="install-latest-rails-version--801">Install Latest Rails Version – 8.0.1</h4>
<p>You can find the latest version information on the <a href="https://rubyonrails.org">Ruby on Rails Website</a></p>

<p><code class="language-plaintext highlighter-rouge">$ gem install rails --version 8.0.1 --no-document</code></p>

<p><a href="#list-of-steps">Return to Steps</a></p>

<h4 id="generate-new-rails-app-with-postgresql">Generate New Rails App with PostgreSQL</h4>
<p>At the command line generate a new rails app using postgresql as the database.</p>

<p><code class="language-plaintext highlighter-rouge">$ rails new [new rails 8 app] -d postgresql</code></p>

<p>I got held up by a conflict in the config/cable.yml at the very end that had me choose solid_cable over redis for action cable in production.  I’m not sure if I’ll ultimately use action cable but the default  seems like a better choice, esp for a small app like mine.</p>

<p><code class="language-plaintext highlighter-rouge">$ cd [new rails 8 app]</code></p>

<p><a href="#list-of-steps">Return to Steps</a></p>

<h4 id="add-ruby-version-and-gemset-dotfiles">Add Ruby Version and Gemset Dotfiles</h4>
<p>To keep the ruby version and gemset consistent for RVM and collaborators, create dot files for <code class="language-plaintext highlighter-rouge">.ruby-version</code> and <code class="language-plaintext highlighter-rouge">.ruby-gemset</code> and add the appropriate content:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>$ echo "ruby-3.3.7" &gt; .ruby-version
$ echo "[new app name]" &gt; .ruby-gemset
</code></pre></div></div>
<p>Resource rvm with:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>$ cd .. &amp;&amp; cd [new app name]
</code></pre></div></div>
<p><a href="#list-of-steps">Return to Steps</a></p>
<h4 id="update-gemfile-with-ruby-version-and-dotenv-rails-gem">Update Gemfile with Ruby Version and <code class="language-plaintext highlighter-rouge">dotenv-rails</code> Gem</h4>
<p>To the <code class="language-plaintext highlighter-rouge">Gemfile</code> add:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code># Gemfile
ruby “3.3.7”
group :development, :test do
  gem "dotenv-rails", "~&gt; 2.1"
end
</code></pre></div></div>
<h4 id="update-env-file">Update <code class="language-plaintext highlighter-rouge">.env</code> File</h4>
<p>Confirm that <code class="language-plaintext highlighter-rouge">.env</code> is in the <code class="language-plaintext highlighter-rouge">.gitignore</code> file.  <code class="language-plaintext highlighter-rouge">/.env*</code> automatically gets generated by rails so you should be all set.<br />
Do add <code class="language-plaintext highlighter-rouge">.DS_Store</code> to <code class="language-plaintext highlighter-rouge">.gitignore</code> while you’re thinking about that file.
With your Gemfile updated run <code class="language-plaintext highlighter-rouge">$ bundle install</code>
Next create and modify the <code class="language-plaintext highlighter-rouge">.env</code> file: <code class="language-plaintext highlighter-rouge">$ touch .env</code> and it’s contents will be:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code># .env
DB_NAME_DEVELOPMENT=[app name]_development
DB_NAME_TEST=[app name]_test
DB_USERNAME=[system username]
DB_PASSWORD=””
</code></pre></div></div>
<p><a href="#list-of-steps">Return to Steps</a></p>
<h4 id="update-databaseyml-and-create-local-postgresql-databases-with-binrails-dbcreate">Update database.yml and Create Local PostgreSQL Databases with <code class="language-plaintext highlighter-rouge">bin/rails db:create</code></h4>
<p>Next modify the <code class="language-plaintext highlighter-rouge">config/database.yml</code> file with:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code># config/database.yml
default: &amp;default
  adapter: postgresql
  encoding: unicode
  pool: &lt;%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %&gt;
  username: &lt;%= ENV["DB_USERNAME"] %&gt;
  password: &lt;%= ENV["DB_PASSWORD"] %&gt;
  host: &lt;%= ENV.fetch("DB_HOST") { "localhost" } %&gt;

development:
  &lt;&lt;: *default
  database: &lt;%= ENV["DB_NAME_DEVELOPMENT"] || "[new app name]_development" %&gt;

test:
  &lt;&lt;: *default
  database: &lt;%= ENV["DB_NAME_TEST"] || "[new app name]_test" %&gt;

production:
  primary: &amp;primary_production
    &lt;&lt;: *default
    url: &lt;%= ENV["DATABASE_URL"] %&gt;
    database: &lt;%= ENV["DB_NAME_PRODUCTION"] || "[new app name]_production" %&gt;
    username: &lt;%= ENV["DB_USERNAME"] || "[new app name]" %&gt;
    password: &lt;%= ENV["[new app name]_DATABASE_PASSWORD"] %&gt;

  cache:
    &lt;&lt;: *primary_production
    database: &lt;%= ENV["DB_NAME_CACHE"] || "[new app name]_production_cache" %&gt;
    migrations_paths: db/cache_migrate

  queue:
    &lt;&lt;: *primary_production
    database: &lt;%= ENV["DB_NAME_QUEUE"] || "[new app name]_production_queue" %&gt;
    migrations_paths: db/queue_migrate

  cable:
    &lt;&lt;: *primary_production
    database: &lt;%= ENV["DB_NAME_CABLE"] || "[new app name]_production_cable" %&gt;
    migrations_paths: db/cable_migrate
</code></pre></div></div>
<p>Next create the local databases with:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code># bash
$ bin/rails db:create
</code></pre></div></div>
<p>It’s a good idea to commit and backup at this point if you haven’t done so already.</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code># bash
$ git init
$ git add .
$ git commit -m "Initial commit with Rails 8.0.1 and pg"
</code></pre></div></div>
<p>Backup the code on <a href="https://github.com">GitHub</a> by creating a new respository there which is pretty straitforward but there are explicit instructions at <a href="https://docs.github.com/en/repositories/creating-and-managing-repositories/quickstart-for-repositories">https://docs.github.com/en/repositories/creating-and-managing-repositories/quickstart-for-repositories</a>.</p>

<p>Pushing my code up to my new repository generated an error:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code> ! [remote rejected] main -&gt; main (refusing to allow a Personal Access Token to create or update workflow `.github/workflows/ci.yml` without `workflow` scope)
error: failed to push some refs to 'https://github.com/[My Username]/[new repository name].git'
</code></pre></div></div>
<p>I had never had that problem before but just needed to add <code class="language-plaintext highlighter-rouge">workflow</code> to the scope of my classic PAT that I had already created.  Onward!</p>

<p><a href="#list-of-steps">Return to Steps</a></p>

<h4 id="add-procfile-for-heroku-deployment">Add Procfile for Heroku Deployment</h4>
<p>Heroku recommends setting up a <a href="https://devcenter.heroku.com/articles/procfile">Procfile</a> which specifies the commands executed when your app starts up.</p>

<p>On <a href="https://devcenter.heroku.com/articles/getting-started-with-rails8#create-a-procfile">Heroku’s Getting Started with Rails 8</a> page they suggest a basic <code class="language-plaintext highlighter-rouge">Profile</code> with just:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>web: bundle exec puma -C config/puma.rb
</code></pre></div></div>
<p>And that is what I’m using for now.  As the sole line in the <code class="language-plaintext highlighter-rouge">Procfile</code> suggests, you need a <code class="language-plaintext highlighter-rouge">config/puma.rb</code> file but one got generated automatically which will hopefully be fine for now.
<a href="#list-of-steps">Return to Steps</a></p>

<h4 id="create-heroku-app">Create Heroku App</h4>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>$ heroku create [new heroku app name]
</code></pre></div></div>
<p>Confirm that a heroku git remote was created with:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>$ git config --list --local | grep heroku
</code></pre></div></div>
<p><a href="#list-of-steps">Return to Steps</a></p>
<h4 id="provision-heroku-database-in-new-app">Provision Heroku Database in New App</h4>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>$ heroku addons:create heroku-postgresql:essential-0
Creating heroku-postgresql:essential-0 on ⬢ [new heroku app]... ~$0.007/hour (max $5/month)
Database should be available soon
postgresql-[random word-random number] is being created in the background. The app will restart when complete...
Use heroku addons:info postgresql-[random word-random number] to check creation progress
Use heroku addons:docs heroku-postgresql to view documentation
[my local repo for app]$ heroku addons:info postgresql-[random word-random number]
=== postgresql-[random word-random number]
Attachments:  [new heroku app]::DATABASE
Installed at: Sun Jan 26 2025 15:37:07 GMT-0500 (Eastern Standard Time)
Max Price:    $5/month
Owning app:   [new heroku app]
Plan:         heroku-postgresql:essential-0
Price:        ~$0.007/hour
State:        created
</code></pre></div></div>
<p>Commit and push to GitHub and Heroku</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>$ git push &amp;&amp; git push heroku main
</code></pre></div></div>
<p><a href="#list-of-steps">Return to Steps</a></p>
<h4 id="specify-version-constraints-in-gemfile">Specify Version Constraints in Gemfile</h4>
<p>I then spent a lot of time adding version constraints to my <code class="language-plaintext highlighter-rouge">Gemfile</code>.  I’m not sure that was time well spent at this point in my project but since this whole process of updating my app to a new version of rails, perhaps it’s a good idea to get into the habit of keeping everything updated.  I note that adding <code class="language-plaintext highlighter-rouge">~&gt;</code> and related code also requires periodic <code class="language-plaintext highlighter-rouge">bundle update</code> to do anything.  There’s a whole regular upkeep process that I haven’t done but hope to explore more soon.  First got to get the app working on rails 8.</p>

<p>As for the <code class="language-plaintext highlighter-rouge">Gemfile</code>, what I did was have ChatGPT study my <code class="language-plaintext highlighter-rouge">Gemfile</code> and generate a list of gems that didn’t have version constraints (it actually missed some but found them when I pointed that out.)  Then I ran the following commands to find the versions currentlly being used:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>#bash
$ gem list | grep -E "propshaft|importmap-rails|turbo-rails|stimulus-rails|jbuilder|solid_cache|solid_queue|solid_cable|bootsnap|kamal|thruster|web-console|capybara|selenium-webdriver|debug|brakeman|rubocop-rails-omakase"
bootsnap (1.18.4)
brakeman (7.0.0)
capybara (3.40.0)
debug (1.10.0, 1.9.2)
importmap-rails (2.1.0)
jbuilder (2.13.0)
kamal (1.9.2)
propshaft (1.1.0)
rubocop-rails-omakase (1.0.0)
selenium-webdriver (4.28.0)
solid_cable (3.0.6)
solid_cache (1.0.6)
solid_queue (1.1.2)
stimulus-rails (1.3.4)
thruster (0.1.10 arm64-darwin)
turbo-rails (2.0.11)
web-console (4.2.1)
</code></pre></div></div>

<p>My new Gemfile with Version Constraints:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>source "https://rubygems.org"

ruby "3.3.7"

# Bundle edge Rails instead: gem "rails", github: "rails/rails", branch: "main"
gem "rails", "~&gt; 8.0.1"
# The modern asset pipeline for Rails [https://github.com/rails/propshaft]
gem "propshaft", "~&gt; 1.1.0"
# Use postgresql as the database for Active Record
gem "pg", "~&gt; 1.1"
# Use the Puma web server [https://github.com/puma/puma]
gem "puma", "&gt;= 5.0"
# Use JavaScript with ESM import maps [https://github.com/rails/importmap-rails]
gem "importmap-rails", "~&gt; 2.1.0"
# Hotwire's SPA-like page accelerator [https://turbo.hotwired.dev]
gem "turbo-rails", "~&gt; 2.0.11"
# Hotwire's modest JavaScript framework [https://stimulus.hotwired.dev]
gem "stimulus-rails", "~&gt; 1.3.4"
# Build JSON APIs with ease [https://github.com/rails/jbuilder]
gem "jbuilder", "~&gt; 2.13.0"

# For managing environment variables in development and testing

# Use Active Model has_secure_password [https://guides.rubyonrails.org/active_model_basics.html#securepassword]
# gem "bcrypt", "~&gt; 3.1.7"

# Windows does not include zoneinfo files, so bundle the tzinfo-data gem
gem "tzinfo-data", platforms: %i[ windows jruby ]

# Use the database-backed adapters for Rails.cache, Active Job, and Action Cable
gem "solid_cache", "~&gt; 1.0.6"
gem "solid_queue", "~&gt; 1.1.2"
gem "solid_cable", "~&gt; 3.0.6"

# Reduces boot times through caching; required in config/boot.rb
gem "bootsnap", "~&gt; 1.18.4", require: false

# Deploy this application anywhere as a Docker container [https://kamal-deploy.org]
gem "kamal", "~&gt; 1.9.2", require: false

# Add HTTP asset caching/compression and X-Sendfile acceleration to Puma [https://github.com/basecamp/thruster/]
gem "thruster", "~&gt; 0.1.10", require: false

# Use Active Storage variants [https://guides.rubyonrails.org/active_storage_overview.html#transforming-images]
# gem "image_processing", "~&gt; 1.2"

group :development, :test do
  # See https://guides.rubyonrails.org/debugging_rails_applications.html#debugging-with-the-debug-gem
  gem "debug", "~&gt; 1.10.0", platforms: %i[ mri windows ], require: "debug/prelude"

  # Static analysis for security vulnerabilities [https://brakemanscanner.org/]
  gem "brakeman", "~&gt; 7.0.0", require: false

  # Omakase Ruby styling [https://github.com/rails/rubocop-rails-omakase/]
  gem "rubocop-rails-omakase", "~&gt; 1.0.0", require: false
end

# to store environment variables in development and test
group :development, :test do
  gem "dotenv-rails", "~&gt; 2.1"
end

group :development do
  # Use console on exceptions pages [https://github.com/rails/web-console]
  gem "web-console", "~&gt; 4.2.1"
end

group :test do
  # Use system testing [https://guides.rubyonrails.org/testing.html#system-testing]
  gem "capybara", "~&gt; 3.40.0"
  gem "selenium-webdriver", "~&gt; 4.28.0"
end
</code></pre></div></div>
<p>Now <code class="language-plaintext highlighter-rouge">$ bundle install</code>, commit and push to github and heroku.</p>

<p><a href="#list-of-steps">Return to Steps</a></p>

<h4 id="backup-legacy-database-on-heroku">Backup Legacy Database on Heroku</h4>
<p>Check out the Heroku page on backups at: <a href="https://devcenter.heroku.com/articles/heroku-postgres-backups">https://devcenter.heroku.com/articles/heroku-postgres-backups</a>
Confirm the current backups of your legacy app with:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>$ heroku pg:backups --app [legacy app]
</code></pre></div></div>
<p>Consider deleting old backups to get rid of obsolete data and/or make room for new backups.  The command is:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>$ heroku pg:backups:delete [database ID] --app [legacy app]
</code></pre></div></div>
<p>Backup the legacy database:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>$ heroku pg:backups:capture --app [legacy database]
</code></pre></div></div>
<p>Check that the backup you just made is now in the list of backups with:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>$ heroku pg:backups --app [legacy database]
</code></pre></div></div>
<p>Ok.  So, I’m getting tired of transcibing my notes for the interwebs.  I might continue later or I might just keep going.  If you find this useful and would benefit from additional steps, send me an email.  Thanks for understanding!  Best!</p>

<p><a href="#list-of-steps">Return to Steps</a></p>
<h4 id="copy-legacy-database-to-new-heroku-app">Copy Legacy Database to New Heroku App</h4>
<p>(Add content here)</p>

<p><a href="#list-of-steps">Return to Steps</a></p>

<h4 id="check-postgresql-version-in-new-apps-database-and-match-up-postgresql-version-locally">Check PostgreSQL Version in New App’s Database and Match up PostgreSQL Version Locally</h4>
<p>(Add content here)</p>

<p><a href="#list-of-steps">Return to Steps</a></p>

<h4 id="download-the-legacy-database-and-restore-it-locally">Download the Legacy Database and Restore It Locally</h4>
<p>(Add content here)</p>

<p><a href="#list-of-steps">Return to Steps</a></p>

<h4 id="run-binrails-dbschemadump-to-recreate-the-legacy-database-schema-in-the-new-app">Run <code class="language-plaintext highlighter-rouge">bin/rails db:schema:dump</code> to Recreate the Legacy Database Schema in the New App</h4>
<p>(Add content here)</p>

<p><a href="#list-of-steps">Return to Steps</a></p>

<h4 id="add-appmodels-files-to-initialize-models-for-testing-in-the-rails-console">Add <code class="language-plaintext highlighter-rouge">app/models</code> Files to Initialize Models for Testing in the Rails Console</h4>
<p>(Add content here)</p>

<p><a href="#list-of-steps">Return to Steps</a></p>

<h4 id="use-rails-console-to-test-access-to-legacy-database">Use Rails Console to Test Access to Legacy Database</h4>
<p>(Add content here)</p>

<p><a href="#list-of-steps">Return to Steps</a></p>

<h4 id="commit-and-push-code-to-heroku">Commit and Push Code to Heroku</h4>
<p>(Add content here)</p>

<p><a href="#list-of-steps">Return to Steps</a></p>

<h4 id="use-heroku-rails-console-to-test-access-to-database">Use <code class="language-plaintext highlighter-rouge">heroku rails console</code> to Test Access to Database</h4>
<p>(Add content here)</p>

<p><a href="#list-of-steps">Return to Steps</a></p>

<h4 id="use-heroku-rails-console-to-obscure-any-sensitive-data">Use <code class="language-plaintext highlighter-rouge">heroku rails console</code> to Obscure Any Sensitive Data</h4>
<p>(Add content here)</p>

<p><a href="#list-of-steps">Return to Steps</a></p>]]></content><author><name>Ben Unger</name></author><category term="coding" /><category term="rails" /><category term="heroku" /><category term="rails-8" /><category term="postgresql" /><category term="heroku" /><category term="resources" /><category term="legacy-database" /><summary type="html"><![CDATA[How I created a new Rails 8 app and got it working locally and on Heroku using a legacy database.]]></summary><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://benjaminunger.com/assets/images/og-default.jpg" /><media:content medium="image" url="https://benjaminunger.com/assets/images/og-default.jpg" xmlns:media="http://search.yahoo.com/mrss/" /></entry><entry><title type="html">Fixing Google Analytics for Jekyll Minima: Lessons Learned</title><link href="https://benjaminunger.com/coding/jekyll/2025/01/23/fixing-google-analytics-for-jekyll-minima-lessons-learned.html" rel="alternate" type="text/html" title="Fixing Google Analytics for Jekyll Minima: Lessons Learned" /><published>2025-01-23T11:04:58-05:00</published><updated>2025-01-23T11:04:58-05:00</updated><id>https://benjaminunger.com/coding/jekyll/2025/01/23/fixing-google-analytics-for-jekyll-minima-lessons-learned</id><content type="html" xml:base="https://benjaminunger.com/coding/jekyll/2025/01/23/fixing-google-analytics-for-jekyll-minima-lessons-learned.html"><![CDATA[<p>For anyone using Jekyll’s Minima theme this post describes how I resolved an issue with outdated Google Analytics integration and maybe saving you some frustration.  I’m embarrassed by how long it took me to fix but  learned a lot along the way.</p>

<h2 id="the-problem">The Problem</h2>
<p>The <code class="language-plaintext highlighter-rouge">_includes/google-analytics.html</code> file in the Minima theme uses an old Universal Analytics script, which no longer works for GA4 tracking IDs. It took me a while to figure out the problem first trying using the minima theme remotely as someone suggested somewhere.</p>

<p><a href="https://grechin.org/2021/03/30/adding-google-analytics-to-minima.html">This post</a> by <a href="https://grechin.org">Sergey Gretchin</a> pointed to the problem of the outdated minima code at <a href="https://github.com/jekyll/minima/blob/master/_includes/google-analytics.html">Jekyll/minima/_includes/google-analytics.html</a>.  You’ve got to make your own <code class="language-plaintext highlighter-rouge">_includes/google-analytics.html</code> file with either the script strait from Google Analytics or with a reference using Liquid to {{ site.google_analytics }}.</p>

<h2 id="hours-wasted-on-underscore-vs-hyphen-confusion">Hours Wasted on Underscore vs. Hyphen Confusion</h2>
<p>You’d think that it would be pretty easy to put <code class="language-plaintext highlighter-rouge">google_analytics: G-[YOUR GOOGLE ANALYTICS CODE]</code> into your <code class="language-plaintext highlighter-rouge">_config.yml</code> file.  That’s what I thought I did but Google Analytics still didn’t work.  Only after hours of blood, sweat and tears did I realize that I had put <code class="language-plaintext highlighter-rouge">google-analytics</code> in my <code class="language-plaintext highlighter-rouge">_config.yml</code> file echoing the <code class="language-plaintext highlighter-rouge">google-analytics.html</code> file name.</p>

<h2 id="ungers-first-open-source-contribution-gets-rejected">Unger’s First Open Source Contribution Gets Rejected</h2>

<p>Problem solved I figured that maybe I could help other folks and save them some time by updating the code in the Jekyll minima theme <code class="language-plaintext highlighter-rouge">google-analytics.html</code> file.  I forked.  I pulled.  I made the change.  I added a nice description.  I pushed my code up to GitHub.  For a few seconds I was so proud of myself seeing my spanking new pull request up there with the other 20+ PR’s.  Reading down the list I soon noted that 2 other people had already submitted the same solution.  <a href="https://en.wikipedia.org/wiki/D%27oh!">D’oh!</a></p>

<h2 id="note-to-self-check-the-issues--check-the-existing-pull-requests">Note to Self: Check the Issues.  Check the Existing Pull Requests</h2>

<p>Being as new and inexperienced as I am I’ve historically found the Issues and Pull Requests on GitHub to be too complex for me to follow and understand.  I now see that they can include solutions to problems that I’m struggling with.  And there’s no need to offer the same solution that someone else already has.  It took only 3 minutes for my PR rejection as redundant.  All interesting and fun, though.</p>]]></content><author><name>Ben Unger</name></author><category term="coding" /><category term="jekyll" /><category term="jekyll" /><category term="google-analytics" /><category term="minima-theme" /><category term="getting-stuck" /><category term="resources" /><summary type="html"><![CDATA[How I resolved issues with outdated Google Analytics integration in Jekyll's Minima theme.]]></summary><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://benjaminunger.com/assets/images/og-default.jpg" /><media:content medium="image" url="https://benjaminunger.com/assets/images/og-default.jpg" xmlns:media="http://search.yahoo.com/mrss/" /></entry><entry><title type="html">Updating Rails 6 app to Rails 8</title><link href="https://benjaminunger.com/coding/rails/2025/01/22/updating-rails-6-app.html" rel="alternate" type="text/html" title="Updating Rails 6 app to Rails 8" /><published>2025-01-22T07:31:58-05:00</published><updated>2025-01-22T07:31:58-05:00</updated><id>https://benjaminunger.com/coding/rails/2025/01/22/updating-rails-6-app</id><content type="html" xml:base="https://benjaminunger.com/coding/rails/2025/01/22/updating-rails-6-app.html"><![CDATA[<blockquote>
  <p><em>“Coding is easy.  Setup and maintenance are hard.”</em>
    – Lots of coders everywhere</p>
</blockquote>

<p>I’ve got an old app that’s not too complicated that my old anesthesia department has used daily for over 10 years,  It’s currently using Rails 6.1.6 and ruby 2.7.2 that Heroku will no longer let me update starting this coming May 1, 2025.  So, time to upgrade.  I’ve gone through this process twice before.  I’ve tried twice on my own before getting hopelessly stuck and having to call in the cavalry, a real coder named <a href="https://www.linkedin.com/in/mykl-clason-52a982138/">Mykl Clason</a>.  (It’s pronounced like “Michael.”  You can thank his mom for the spelling who knew that it would build character.) He’s very skilled and patient and rescued me both times.  This time I’m taking a break from full time work so might have more time and energy to focus on the upgrade.  Fingers crossed.</p>

<h2 id="best-practices">Best Practices</h2>

<p><a href="https://guides.rubyonrails.org/index.html">The Rails Guides</a> provides some guidance on <a href="https://guides.rubyonrails.org/upgrading_ruby_on_rails.html">Upgrading Ruby on Rails</a>.  They suggest several things: don’t upgrade unless you really need to, great test coverage on the original app and then upgrading slowly, ruby first, and then rails, latest patch version of current version and then to the next version.  You fix deprecation warnings and failed tests as you go.</p>

<p>That’s excellent advice.  But truth be told, I couldn’t keep up with test coverage long ago.  For starters, the tests started to take too long to run on my computer.  Then I had different code that needed to be run on different days of the week.  I’m sure there’s a way but managing and keeping track of time in my test environment and other details broke me back then.  Maybe I can make testing work in rails 8.0.1… ?  Maybe?  I’m going to try.</p>

<h3 id="my-upgrade-approach"><strong>My Upgrade Approach</strong></h3>

<p>My approach will be somewhat different taking into account the relative lack of complexity of my app (I hope) and my time.  Here’s my basic outline:</p>

<ul>
  <li>
    <p><strong>Backup and Upgrade the Database</strong><br />
Use <code class="language-plaintext highlighter-rouge">heroku pg:copy</code> to create a duplicate of the legacy database. This will also upgrade it to the latest PostgreSQL version on Heroku, leaving the original database untouched.</p>
  </li>
  <li>
    <p><strong>Download the Updated Database</strong><br />
Capture a backup of the upgraded database and download it locally for development.</p>
  </li>
  <li>
    <p><strong>Set Up PostgreSQL Locally</strong><br />
Install and configure PostgreSQL on my local machine, then restore the downloaded backup using <code class="language-plaintext highlighter-rouge">pg_restore</code>.</p>
  </li>
  <li>
    <p><strong>Create a Rails 8 App</strong><br />
Generate a new Rails 8.0.1 app with Ruby 3.3.7 and configure it to connect to the restored local database.</p>
  </li>
  <li>
    <p><strong>Rebuild the User Model</strong><br />
Recreate the user model in the new app, excluding outdated authentication fields while preserving other attributes.</p>
  </li>
  <li>
    <p><strong>Test Local Database Access</strong><br />
Verify that the app can interact with the legacy database by running simple queries like <code class="language-plaintext highlighter-rouge">User.first</code> through the Rails console.</p>
  </li>
  <li>
    <p><strong>Deploy to Heroku</strong><br />
Push the Rails 8 app to Heroku and connect it to the duplicated, upgraded database.</p>
  </li>
  <li>
    <p><strong>Expand Models</strong><br />
Recreate the remaining models and ensure proper database interactions both locally and on Heroku.</p>
  </li>
  <li>
    <p><strong>Implement Testing</strong><br />
Start with basic model tests, introduce validations, and progressively build test coverage for the application.</p>
  </li>
  <li>
    <p><strong>Recreate the App</strong><br />
Use test-driven development (TDD) to rebuild the application step by step, ensuring reliability and scalability.</p>
  </li>
</ul>

<p>As I reflect now, it wouldn’t be the worst thing to do to try to upgrade this app as is to later ruby versions and then rails versions.  If I get stuck, I may explore upgrading the existing app incrementally to Rails 7.2 or adding testing coverage to the original app.</p>

<p>This is my initial overall approach but I will document more specific steps and details as I go along in future posts.</p>

<blockquote>
  <p><em>“False starts are starts.  So just start.”</em>
    – Ben Unger</p>
</blockquote>

<p>You don’t really understand the problem space until you start confronting it.</p>

<h2 id="yes-i-will-consult-with-chatgpt">Yes, I will consult with ChatGPT</h2>

<p>ChatGPT does have great insights into a lot of the problems I face.  But you’ve got to keep an eye on it.  It often makes mistakes and gets confused.  We’ll see how useful it is for me with this project.</p>

<h2 id="online-resources-for-testing-and-upgrading">Online Resources for Testing and Upgrading</h2>

<p>I’m definitely sympathetic to TDD for creating robust programs but for now I figure that I should apply that to a new Rails 8 app and give a new app longer life on Heroku.  You can check out the <a href="https://guides.rubyonrails.org/testing.html">Rails Testing Guide</a>.</p>

<p>There’s a great article by <a href="https://remimercier.com/upgrading-ruby-on-rails/">Rémi Mercier</a> about upgrading from Rails 5.2 to Rails 6.0 with details about deprecation warnings, the <code class="language-plaintext highlighter-rouge">rails app:update</code> command, reading changelogs, etc.  It serves as a cautionary tale about how upgrades can quickly become overwhelming without proper planning and careful incremental work.  I didn’t even know what a linter was that he referred to.  (For those of you who, like me, didn’t know what a linter is, it’s a tool that checks your code for style issues and potential bugs, which can be incredibly helpful during an upgrade.)</p>

<h2 id="let-me-hear-from-you">Let me hear from you.</h2>

<p>I haven’t added comments yet, but if you’d like to share your thoughts or experiences, feel free to email me. Have you tackled a Rails upgrade or a similar challenge? I’d love to hear your insights. If I hear from someone, I’ll add a comment section to make discussions easier.</p>]]></content><author><name>Ben Unger</name></author><category term="coding" /><category term="rails" /><category term="rails-6" /><category term="rails-8" /><category term="testing" /><category term="postgresql" /><category term="heroku" /><category term="resources" /><category term="getting-started" /><summary type="html"><![CDATA[Initial thoughts on tackling updating a Rails 6.1.6 app to Rails 8 deployed on Heroku.]]></summary><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://benjaminunger.com/assets/images/og-default.jpg" /><media:content medium="image" url="https://benjaminunger.com/assets/images/og-default.jpg" xmlns:media="http://search.yahoo.com/mrss/" /></entry><entry><title type="html">Looking for a Jekyll Theme</title><link href="https://benjaminunger.com/coding/jekyll/getting-started/2025/01/21/looking-for-a-jekyll-theme.html" rel="alternate" type="text/html" title="Looking for a Jekyll Theme" /><published>2025-01-21T12:23:58-05:00</published><updated>2025-01-21T12:23:58-05:00</updated><id>https://benjaminunger.com/coding/jekyll/getting-started/2025/01/21/looking-for-a-jekyll-theme</id><content type="html" xml:base="https://benjaminunger.com/coding/jekyll/getting-started/2025/01/21/looking-for-a-jekyll-theme.html"><![CDATA[<p>As of the time of writing, this blog uses the default Jekyll theme, the <a href="https://github.com/jekyll/minima">minima</a> theme.  I remain amazed at how easy it is to get a blog up and running with Jekyll and hosting it for free on Github Pages.  That said, the default minima theme isn’t great.  I know I can do better.</p>

<h2 id="jekyll-theme-resources">Jekyll Theme Resources</h2>

<p>You can find an updated list in the <a href="https://jekyllrb.com/docs/themes/">Jekyll Docs</a></p>

<h2 id="hopes-for-a-theme">Hopes for a Theme</h2>

<ol>
  <li>Looks good at baseline</li>
  <li>Media responsive.  It should look good on various devices and screen sizes.</li>
  <li>Blog and photo focused</li>
  <li>Allows me to modify things like fonts and colors without too much trouble</li>
  <li>Allows me to add Google Analytics without too much trouble.</li>
</ol>

<h2 id="should-i-pay-for-a-theme">Should I Pay for a Theme?</h2>
<h3 id="not-yet-but-hopefully-soon">Not yet but hopefully soon.</h3>

<p>I like the idea of buying a theme for a number of reasons.  I like the idea of rewarding someone for his or her efforts.  Also, if you get what you pay for I might get a better looking theme with better features.  There also may be branding advantages to using a theme that fewer people use because of the payment hurdle.</p>

<p>All that said, I’m reluctant to pay for something that I may not use on a long-term basis.  If I continue to get value from this blog – and anyone else gets value from it – then I’ll invest more in it.  I like to prove the concept on the cheap.  I’ll invest once something has traction and staying power.</p>

<h2 id="update--found-a-theme">Update – Found a Theme</h2>

<p>Ok.  So I landed on the <a href="https://startbootstrap.com">Start Bootstrap’s</a> <a href="https://github.com/StartBootstrap/startbootstrap-clean-blog-jekyll">Clean Blog</a> theme.  It looks like it will serve my purposes well.  There’s still some setting up to do following the instructions at the <a href="https://github.com/StartBootstrap/startbootstrap-clean-blog-jekyll">Clean Blog GitHub Page</a> but spoons gone, brain fried.</p>

<h2 id="update--returned-to-minima">Update – Returned to Minima</h2>

<p>I’m not so excited about spending time customizing the styling and just want to record some thoughts and what I’m up to.  So I’m back to minima which I think will serve me well at least for now.</p>]]></content><author><name>Ben Unger</name></author><category term="coding" /><category term="jekyll" /><category term="getting-started" /><category term="resources" /><category term="jekyll" /><category term="themes" /><summary type="html"><![CDATA[Some initial thoughts on what I'm looking for in a Jekyll Theme.]]></summary><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://benjaminunger.com/assets/images/og-default.jpg" /><media:content medium="image" url="https://benjaminunger.com/assets/images/og-default.jpg" xmlns:media="http://search.yahoo.com/mrss/" /></entry><entry><title type="html">Hello World! Coding, cooking, home repair, healing, patient care and life.</title><link href="https://benjaminunger.com/coding/blogging/jekyll/getting-started/productivity/2025/01/20/hello-there-world.html" rel="alternate" type="text/html" title="Hello World! Coding, cooking, home repair, healing, patient care and life." /><published>2025-01-20T17:42:58-05:00</published><updated>2025-01-20T17:42:58-05:00</updated><id>https://benjaminunger.com/coding/blogging/jekyll/getting-started/productivity/2025/01/20/hello-there-world</id><content type="html" xml:base="https://benjaminunger.com/coding/blogging/jekyll/getting-started/productivity/2025/01/20/hello-there-world.html"><![CDATA[<p>Hello, World!  I hope to use this little corner of the internet to document my adventures in coding, cooking, home repair, healing, health, patient care and life.  With that done I’m exhausted.</p>

<h2 id="adventures-in-ice-management">Adventures in Ice Management</h2>

<p>Why am I so tired?  What did I do today?  For starters I spread salt and sand on my driveway and on the sidewalk in front of my house.  4 inches of snow fell overnight out here in metro-Boston.  I’ve got a home salt spreaders but after 5 winters it’s on its last legs.  I first noticed that its bolts had rusted as I filled it alternatively with sand and salt.  Then I struggled to push it around only for it to leave a narrow ribbon of salt and sand.  So much for spreading.  Only after I had distributed all of the salt and sand emptying the hopper did I notice that the spreading mechanism had broken and that the wheel that ran it had frozen in place.  I’ll look at that more closely another day.  You’d think that such spreaders would have more corrosion resistance but that likely costs more than folks like me are willing to pay.  So I had to spread out all of those ribbons with a broom myself.  Not the hardest task in the world.  I actually found the sweeping meditative and relaxing.  But it was chilly.</p>

<h2 id="home-improvement-wins-and-setbacks">Home Improvement Wins and Setbacks</h2>

<p>My driveway taken care of I headed to Home Depot where I bought  a replacement dimmer as well as the tools needed to replace the current one.  Retailers no longer sell most incandescent bulbs in the USA.  The old dimmer can’t handle the new, low wattage, LED bulbs which flicker in a way that my wife finds maddening.</p>

<p>My first solution involved changing the LED 60W replacements with 40W incandescent bulbs that they still sell.  Those specilized bulbs were designed to go in appliances like fridges and stoves.  That change solved the flicker problem but also reduced the light by maybe a third.  I think I can do better with a new dimmer designed for LED bulbs.  Off to Home Depot for me.</p>

<p>My purchase at HD went uneventfully but when I got home I realized that the grey dimmer I had purchased didn’t match the white plate.  2nd act of the day?  Returned to Home Depot to swap out the dimmer a bought for a white one.  This would be my first return at Home Depot and I worried about lines and hassle by customer service but shouldn’t have.  I experienced neither.  The exchange was easy as pie.</p>

<h2 id="some-vegetarian-meal-prep-for-this-reducetarian">Some Vegetarian Meal Prep for this Reducetarian</h2>

<p>Everything for that project lined up, I turned my attention to cooking.  I roasted some potatoes as well as some eggplants, the latter destined for <a href="https://cookieandkate.com/epic-baba-ganoush-recipe/">baba ganoush</a>.  At the same time I also simmered the garbonzo beans I had soaked overnight for some <a href="https://www.seriouseats.com/israeli-style-extra-smooth-hummus-recipe">scratch hummus</a>.  Everything came out delish but the clean up took a lot out of me (and I don’t have a lot in me to begin with.)</p>

<h2 id="setting-up-the-blog">Setting up the Blog</h2>

<p>Still, I’ve been eager to set up a blog so I spent the last couple of hours getting this bare bones blog up and running using <a href="https://jekyllrb.com">Jekyll</a> and hosted for free on <a href="https://github.com">GitHub</a> using <a href="https://pages.github.com">Github Pages</a>.  More details and instructions on using Jekyll and GitHub Pages together can be found <a href="https://docs.github.com/en/pages/setting-up-a-github-pages-site-with-jekyll">here</a>.  Not much to show for my efforts but still – <a href="https://en.wikipedia.org/wiki/Spoon_theory">spoons</a> gone, brain fried.</p>

<h2 id="updates--health-and-pacing">Updates:  Health and Pacing</h2>

<p>UPDATE:  Did about 15 minutes of time on the exercise bike followed by some stretching and felt better.  More about exercise later.</p>

<p>UPDATE 2: Woke up this morning (the morning after writing the above post) with a sore throat.  I’ve had mild systemic symptoms – sinusitis, myalgias, pharyngitis (sore throat), fatigue, cold intolerance – for about 5 days now and the sore throat is a reminder that I’m still likely fighting something off or still tired from the fight.  Fatigue can linger long after other symptoms.  So, I’ll pace myself and stay hydrated.</p>

<h2 id="next-steps-for-the-blog-and-beyond">Next Steps for the Blog and Beyond</h2>

<ol>
  <li>Find a better theme and make this site look a little better.</li>
  <li>Remove all of the default content that comes automatically with a new Jekyll app.</li>
  <li>Add Google analytics.  Will anyone find anything interesting here?  I’m gonna find out.</li>
  <li>Consider adding comments.  Not likely worth the effort to add and monitor if no one reads this anyway.  Readers can always email me if they really want to let me know something.</li>
  <li>Add a post about what I’m up to and working on.</li>
  <li>Get cracking.</li>
  <li>Lather, rinse and return to step 5.</li>
</ol>]]></content><author><name>Ben Unger</name></author><category term="coding" /><category term="blogging" /><category term="jekyll" /><category term="getting-started" /><category term="productivity" /><category term="first-post" /><category term="resources" /><category term="next-steps" /><category term="spoons" /><summary type="html"><![CDATA[A first Jekyll-powered blog post reflecting on a day of snow clearing, home improvement, cooking, and setting up this site. Includes next steps for improving the blog and personal reflections on energy levels and pacing.]]></summary><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://benjaminunger.com/assets/images/og-default.jpg" /><media:content medium="image" url="https://benjaminunger.com/assets/images/og-default.jpg" xmlns:media="http://search.yahoo.com/mrss/" /></entry></feed>