<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Evgenii S.</title>
    <description>The latest articles on DEV Community by Evgenii S. (@enjaku4).</description>
    <link>https://dev.to/enjaku4</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F1457588%2F3fdab518-0607-444f-beec-74c32a2c1d53.jpeg</url>
      <title>DEV Community: Evgenii S.</title>
      <link>https://dev.to/enjaku4</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/enjaku4"/>
    <language>en</language>
    <item>
      <title>Rabarber v6: Major Update for the Rails Role-Based Authorization Gem</title>
      <dc:creator>Evgenii S.</dc:creator>
      <pubDate>Wed, 08 Apr 2026 17:18:24 +0000</pubDate>
      <link>https://dev.to/enjaku4/rabarber-v6-major-update-for-the-rails-role-based-authorization-gem-481i</link>
      <guid>https://dev.to/enjaku4/rabarber-v6-major-update-for-the-rails-role-based-authorization-gem-481i</guid>
      <description>&lt;p&gt;&lt;a href="https://github.com/enjaku4/rabarber" rel="noopener noreferrer"&gt;Rabarber&lt;/a&gt;, a role-based authorization gem for Rails, releases v6.0.0.&lt;/p&gt;

&lt;p&gt;The new version finalizes the API cleanup started in v5, deprecated methods were removed making the API cleaner and more intuitive. Another notable, and hopefully not noticeable, change is the reworked caching mechanism which improves reliability and fixes a bug that prevented Rabarber from working correctly with Memcached.&lt;/p&gt;

&lt;p&gt;This is a major version with breaking changes, so please refer to the &lt;a href="https://github.com/enjaku4/rabarber/discussions/101" rel="noopener noreferrer"&gt;migration guide&lt;/a&gt; when upgrading.&lt;/p&gt;

&lt;p&gt;Check out the gem &lt;a href="https://github.com/enjaku4/rabarber" rel="noopener noreferrer"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Happy coding!&lt;/p&gt;

</description>
      <category>rails</category>
      <category>security</category>
      <category>ruby</category>
      <category>news</category>
    </item>
    <item>
      <title>Veri v2.0: Important Fixes for Rails Authentication Gem</title>
      <dc:creator>Evgenii S.</dc:creator>
      <pubDate>Tue, 06 Jan 2026 12:27:29 +0000</pubDate>
      <link>https://dev.to/enjaku4/veri-v20-important-fixes-for-rails-authentication-gem-1ab1</link>
      <guid>https://dev.to/enjaku4/veri-v20-important-fixes-for-rails-authentication-gem-1ab1</guid>
      <description>&lt;p&gt;&lt;a href="https://github.com/enjaku4/veri" rel="noopener noreferrer"&gt;Veri&lt;/a&gt;, a minimal authentication framework for Rails, releases v2.0. This release fixes the major user impersonation issue that existed in v1. Upgrading is highly recommended.&lt;/p&gt;

&lt;p&gt;Since this is a major version with breaking changes, please review the &lt;a href="https://github.com/enjaku4/veri/discussions/14" rel="noopener noreferrer"&gt;migration guide&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Check out the gem &lt;a href="https://github.com/enjaku4/veri" rel="noopener noreferrer"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Happy coding!&lt;/p&gt;

</description>
      <category>ruby</category>
      <category>rails</category>
      <category>webdev</category>
      <category>security</category>
    </item>
    <item>
      <title>Grepfruit v3.2: Programmatic API for Text Search</title>
      <dc:creator>Evgenii S.</dc:creator>
      <pubDate>Sat, 03 Jan 2026 12:39:31 +0000</pubDate>
      <link>https://dev.to/enjaku4/grepfruit-v32-programmatic-api-for-text-search-2ia1</link>
      <guid>https://dev.to/enjaku4/grepfruit-v32-programmatic-api-for-text-search-2ia1</guid>
      <description>&lt;p&gt;&lt;a href="https://github.com/enjaku4/grepfruit" rel="noopener noreferrer"&gt;Grepfruit&lt;/a&gt;, a ractor-powered text search gem, adds a programmatic API in v3.2, a count-only mode, and Ruby 4 support.&lt;/p&gt;

&lt;h2&gt;
  
  
  What's new?
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Programmatic API
&lt;/h3&gt;

&lt;p&gt;The gem can now be used programmatically directly in Ruby applications:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="no"&gt;Grepfruit&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;search&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="ss"&gt;regex: &lt;/span&gt;&lt;span class="sr"&gt;/TODO/&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
  &lt;span class="ss"&gt;path: &lt;/span&gt;&lt;span class="s2"&gt;"spec/test_dataset"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
  &lt;span class="ss"&gt;exclude: &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"foo.md"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"baz.py"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="c1"&gt;# returns =&amp;gt;&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="ss"&gt;search: &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="ss"&gt;pattern: &lt;/span&gt;&lt;span class="sr"&gt;/TODO/&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="ss"&gt;directory: &lt;/span&gt;&lt;span class="s2"&gt;"/Users/enjaku/Development/grepfruit/spec/test_dataset"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="ss"&gt;exclusions: &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"foo.md"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"baz.py"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
    &lt;span class="ss"&gt;inclusions: &lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="ss"&gt;summary: &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="ss"&gt;files_checked: &lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="ss"&gt;files_with_matches: &lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="ss"&gt;total_matches: &lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="ss"&gt;matches: &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="ss"&gt;file: &lt;/span&gt;&lt;span class="s2"&gt;"bar.txt"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;line: &lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;content: &lt;/span&gt;&lt;span class="s2"&gt;"TODO: Fix the alignment issue in the header."&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="ss"&gt;file: &lt;/span&gt;&lt;span class="s2"&gt;"bar.txt"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;line: &lt;/span&gt;&lt;span class="mi"&gt;7&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;content: &lt;/span&gt;&lt;span class="s2"&gt;"TODO: Update the user permissions module."&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="ss"&gt;file: &lt;/span&gt;&lt;span class="s2"&gt;"bar.txt"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;line: &lt;/span&gt;&lt;span class="mi"&gt;14&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;content: &lt;/span&gt;&lt;span class="s2"&gt;"TODO: Review the new design specifications."&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="ss"&gt;file: &lt;/span&gt;&lt;span class="s2"&gt;"folder/bad.yml"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;line: &lt;/span&gt;&lt;span class="mi"&gt;21&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;content: &lt;/span&gt;&lt;span class="s2"&gt;"# TODO: Add configuration for cache settings"&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;All CLI options are available as keyword arguments, and the API returns structured data that should be easy to work with in Ruby scripts.&lt;/p&gt;

&lt;h3&gt;
  
  
  Count-only mode
&lt;/h3&gt;

&lt;p&gt;Use the &lt;code&gt;--count&lt;/code&gt; flag (or &lt;code&gt;count: true&lt;/code&gt; in the API) to show only match statistics without displaying the actual matches.&lt;/p&gt;

&lt;h3&gt;
  
  
  Ruby 4 support
&lt;/h3&gt;

&lt;p&gt;Grepfruit now supports Ruby 4 and its updated Ractor implementation.&lt;/p&gt;

&lt;p&gt;Check out the gem &lt;a href="https://github.com/enjaku4/grepfruit" rel="noopener noreferrer"&gt;here&lt;/a&gt;.&lt;br&gt;
Happy coding!&lt;/p&gt;

</description>
      <category>ruby</category>
      <category>regex</category>
      <category>cli</category>
      <category>programming</category>
    </item>
    <item>
      <title>Role-Based Authorization for Rails: How We Built Rabarber</title>
      <dc:creator>Evgenii S.</dc:creator>
      <pubDate>Mon, 10 Nov 2025 10:53:36 +0000</pubDate>
      <link>https://dev.to/enjaku4/role-based-authorization-for-rails-how-we-built-rabarber-ahi</link>
      <guid>https://dev.to/enjaku4/role-based-authorization-for-rails-how-we-built-rabarber-ahi</guid>
      <description>&lt;h2&gt;
  
  
  The Problem
&lt;/h2&gt;

&lt;p&gt;We built an admin area for a sales company that included a custom CRM, marketing tools, content management, and internal developer utilities. Different employees had different responsibilities:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Managers&lt;/strong&gt; handled customer calls and notes&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Analysts&lt;/strong&gt; worked with marketing reports&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Accountants&lt;/strong&gt; dealt with invoices&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Administrators&lt;/strong&gt; oversaw everything&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Developers&lt;/strong&gt; maintained internal tools&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The business needed an authorization system that enforced access strictly according to employee responsibilities. When employees left the company, we also needed to revoke their access without deleting accounts and associated historical data.&lt;/p&gt;

&lt;p&gt;Our system needed to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Support different access levels for employees&lt;/li&gt;
&lt;li&gt;Provide admin-managed role assignments&lt;/li&gt;
&lt;li&gt;Preserve user accounts&lt;/li&gt;
&lt;li&gt;Allow revoking access when an employee leaves&lt;/li&gt;
&lt;li&gt;Be secure by default (everything denied unless explicitly permitted)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;We looked at existing solutions but none fit perfectly:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Pundit&lt;/strong&gt; - was too verbose for our taste, we'd need to create policy objects everywhere just to answer questions like "can a manager access Companies controller?"&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;CanCanCan&lt;/strong&gt; - we preferred checks in controllers before business logic runs, not spread across the application.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Other less popular solutions were either too complex or poorly maintained.&lt;/p&gt;

&lt;p&gt;We needed something simpler: &lt;strong&gt;controller-level checks that answer "can this role access this resource?"&lt;/strong&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  The Solution
&lt;/h2&gt;

&lt;p&gt;We created a simple role-based authorization system. It worked so well that we continued to use it across several projects and eventually extracted it into &lt;strong&gt;&lt;a href="https://github.com/enjaku4/rabarber" rel="noopener noreferrer"&gt;Rabarber&lt;/a&gt;&lt;/strong&gt; - a gem that handles role management, storage, and authorization checks while developers simply define the rules.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Note: The code examples use Rabarber 5.2 API, but the concepts are the same as our original implementation.&lt;/em&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Basic Controller Setup
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Admin::BaseController&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="no"&gt;ApplicationController&lt;/span&gt;
  &lt;span class="kp"&gt;include&lt;/span&gt; &lt;span class="no"&gt;Rabarber&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;Authorization&lt;/span&gt;

  &lt;span class="c1"&gt;# Apply authorization checks to all actions&lt;/span&gt;
  &lt;span class="n"&gt;with_authorization&lt;/span&gt;

  &lt;span class="c1"&gt;# Administrators and developers can access everything in the admin area&lt;/span&gt;
  &lt;span class="n"&gt;grant_access&lt;/span&gt; &lt;span class="ss"&gt;roles: &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="ss"&gt;:admin&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:developer&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Assuming users must be authenticated at this point (Devise was configured in &lt;code&gt;ApplicationController&lt;/code&gt;), this basic setup gave us a clean inheritance model, all actions require authorization, and administrators and developers can access everything by default.&lt;/p&gt;

&lt;h3&gt;
  
  
  Specific Controller Rules
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Admin::ClientsController&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="no"&gt;Admin&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;BaseController&lt;/span&gt;
  &lt;span class="n"&gt;grant_access&lt;/span&gt; &lt;span class="ss"&gt;action: :index&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;roles: &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="ss"&gt;:manager&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:analyst&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;index&lt;/span&gt;
    &lt;span class="c1"&gt;# Managers and analysts can see client list&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;

  &lt;span class="n"&gt;grant_access&lt;/span&gt; &lt;span class="ss"&gt;action: :show&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;roles: &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="ss"&gt;:manager&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:analyst&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;show&lt;/span&gt;
    &lt;span class="c1"&gt;# Managers and analysts can see client details&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;

  &lt;span class="n"&gt;grant_access&lt;/span&gt; &lt;span class="ss"&gt;action: :update&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;roles: :manager&lt;/span&gt;
  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;update&lt;/span&gt;
    &lt;span class="c1"&gt;# Only managers can update client info&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;

  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;destroy&lt;/span&gt;
    &lt;span class="c1"&gt;# Only administrators and developers can delete (from base controller)&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Admin::ClientNotesController&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="no"&gt;Admin&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;BaseController&lt;/span&gt;
  &lt;span class="c1"&gt;# Only managers work with client notes&lt;/span&gt;
  &lt;span class="n"&gt;grant_access&lt;/span&gt; &lt;span class="ss"&gt;roles: :manager&lt;/span&gt;

  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;index&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;end&lt;/span&gt;
  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;create&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We followed this pattern throughout the admin area: &lt;code&gt;InvoicesController&lt;/code&gt; let accountants view invoices but only managers could modify them, &lt;code&gt;MarketingReportsController&lt;/code&gt; was analyst-only, and internal dev tools were restricted to developers.&lt;/p&gt;

&lt;p&gt;We even protected developer utilities such as Sidekiq UI with role checks using Rabarber's &lt;code&gt;has_role?&lt;/code&gt; helper and Devise's &lt;code&gt;authenticate&lt;/code&gt; constraint:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="n"&gt;authenticate&lt;/span&gt; &lt;span class="ss"&gt;:user&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;user&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;internal?&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="n"&gt;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;has_role?&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:developer&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
  &lt;span class="n"&gt;mount&lt;/span&gt; &lt;span class="no"&gt;Sidekiq&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;Web&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s1"&gt;'/sidekiq'&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We also needed to hide UI elements that certain roles couldn't access, which we did using view helpers:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight erb"&gt;&lt;code&gt;&lt;span class="cp"&gt;&amp;lt;%=&lt;/span&gt; &lt;span class="n"&gt;visible_to&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:accountant&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:admin&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="cp"&gt;%&amp;gt;&lt;/span&gt;
  &lt;span class="cp"&gt;&amp;lt;%=&lt;/span&gt; &lt;span class="n"&gt;link_to&lt;/span&gt; &lt;span class="s2"&gt;"Invoices"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;admin_invoices_path&lt;/span&gt; &lt;span class="cp"&gt;%&amp;gt;&lt;/span&gt;
&lt;span class="cp"&gt;&amp;lt;%&lt;/span&gt; &lt;span class="k"&gt;end&lt;/span&gt; &lt;span class="cp"&gt;%&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This kept our navigation menu clean - employees only saw links they were authorized to access.&lt;/p&gt;

&lt;h3&gt;
  
  
  Dynamic Rules
&lt;/h3&gt;

&lt;p&gt;Initially, we added dynamic rules for a specific use case: one manager needed exclusive access to user activity reports.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Admin::UserActivityReportsController&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="no"&gt;Admin&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;BaseController&lt;/span&gt;
  &lt;span class="n"&gt;grant_access&lt;/span&gt; &lt;span class="ss"&gt;roles: :analyst&lt;/span&gt;

  &lt;span class="n"&gt;grant_access&lt;/span&gt; &lt;span class="ss"&gt;action: :show&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;roles: :manager&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;if: &lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;current_user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;special_manager?&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;show&lt;/span&gt;
    &lt;span class="c1"&gt;# ...&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Later, we realized this was overengineering. We didn't need a dynamic check - we needed a role:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Admin::UserActivityReportsController&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="no"&gt;Admin&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;BaseController&lt;/span&gt;
  &lt;span class="n"&gt;grant_access&lt;/span&gt; &lt;span class="ss"&gt;roles: &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="ss"&gt;:analyst&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:user_activity_report_viewer&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;

  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;show&lt;/span&gt;
    &lt;span class="c1"&gt;# ...&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then we simply assigned &lt;code&gt;user_activity_report_viewer&lt;/code&gt; to whoever needed it. This pattern applied to all our granular permissions: &lt;code&gt;shop_manager&lt;/code&gt;, &lt;code&gt;blog_editor&lt;/code&gt;, and other roles where a specific work position didn't exist but someone still needed access to parts of the system to do the job.&lt;/p&gt;

&lt;p&gt;That said, dynamic rules still proved themselves useful for edge cases, like time-based access or checking team membership, so we left them for those rare complex scenarios.&lt;/p&gt;

&lt;h3&gt;
  
  
  Role Management Interface
&lt;/h3&gt;

&lt;p&gt;We built a simple admin interface for role management:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Admin::EmployeesRolesController&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="no"&gt;Admin&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;BaseController&lt;/span&gt;
  &lt;span class="n"&gt;grant_access&lt;/span&gt; &lt;span class="ss"&gt;roles: :admin&lt;/span&gt;

  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;index&lt;/span&gt;
    &lt;span class="vi"&gt;@employees&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;User&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;where&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;internal: &lt;/span&gt;&lt;span class="kp"&gt;true&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;# iterate and show roles for each employee&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;

  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;edit&lt;/span&gt;
    &lt;span class="vi"&gt;@employee&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;User&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;find&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;params&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="ss"&gt;:id&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
    &lt;span class="vi"&gt;@available_roles&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;Rabarber&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;roles&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;

  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;update&lt;/span&gt;
    &lt;span class="no"&gt;User&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;find&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;params&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="ss"&gt;:id&lt;/span&gt;&lt;span class="p"&gt;]).&lt;/span&gt;&lt;span class="nf"&gt;assign_roles&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;params&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="ss"&gt;:roles&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt; &lt;span class="c1"&gt;# array of roles [:manager, :blog_editor]&lt;/span&gt;
    &lt;span class="n"&gt;redirect_to&lt;/span&gt; &lt;span class="n"&gt;employees_path&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;notice: &lt;/span&gt;&lt;span class="s1"&gt;'Roles updated'&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;

  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;destroy&lt;/span&gt;
    &lt;span class="no"&gt;User&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;find&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;params&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="ss"&gt;:id&lt;/span&gt;&lt;span class="p"&gt;]).&lt;/span&gt;&lt;span class="nf"&gt;revoke_all_roles&lt;/span&gt;
    &lt;span class="n"&gt;redirect_to&lt;/span&gt; &lt;span class="n"&gt;employees_path&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;notice: &lt;/span&gt;&lt;span class="s1"&gt;'Access revoked'&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This gave administrators a simple UI to assign and revoke roles. When someone left the company, we'd revoke all their roles - keeping their historical data intact while blocking admin area access.&lt;/p&gt;

&lt;p&gt;And when adding new features that required new roles, we'd create them via data migrations:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;AddBlogEditorRole&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="no"&gt;ActiveRecord&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;Migration&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mf"&gt;7.0&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;up&lt;/span&gt;
    &lt;span class="no"&gt;Rabarber&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;create_role&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:blog_editor&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;

  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;down&lt;/span&gt;
    &lt;span class="no"&gt;Rabarber&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;delete_role&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:blog_editor&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;After deployment, the new role would appear in the admin UI, ready to be assigned.&lt;/p&gt;




&lt;h2&gt;
  
  
  When Rabarber Works And When It Doesn't
&lt;/h2&gt;

&lt;p&gt;Rabarber excels when:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Authorization is primarily role-based&lt;/li&gt;
&lt;li&gt;Controller-level checks are sufficient&lt;/li&gt;
&lt;li&gt;You have clear role definitions&lt;/li&gt;
&lt;li&gt;You need a simple role assignment UI&lt;/li&gt;
&lt;li&gt;You're not dealing with complex permission logic&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;However, if you need complex logic like "can user X edit post Y based on ownership, status, and team membership," you most likely need policy-based authorization. In this case, reach for &lt;strong&gt;&lt;a href="https://github.com/varvet/pundit" rel="noopener noreferrer"&gt;Pundit&lt;/a&gt;&lt;/strong&gt; or &lt;strong&gt;&lt;a href="https://github.com/palkan/action_policy" rel="noopener noreferrer"&gt;ActionPolicy&lt;/a&gt;&lt;/strong&gt;, or even use plain Ruby objects - every policy is just a simple class after all.&lt;/p&gt;

&lt;p&gt;You &lt;em&gt;can&lt;/em&gt; mix approaches - Rabarber for most checks and custom policies for edge cases, but keep in mind that this mixed approach only makes sense if your app is primarily role-based with very few exceptions. If your entire app requires complex policies everywhere, a policy-based gem is a better fit from the start.&lt;/p&gt;




&lt;p&gt;So, if your app fits Rabarber's model, check out &lt;a href="https://github.com/enjaku4/rabarber" rel="noopener noreferrer"&gt;Rabarber on GitHub&lt;/a&gt;. The README has comprehensive examples and the gem supports both global and contextual roles for multi-tenant applications, which I'll talk about in a future article.&lt;/p&gt;

</description>
      <category>ruby</category>
      <category>rails</category>
      <category>webdev</category>
      <category>security</category>
    </item>
    <item>
      <title>Veri v1.0: Minimal Rails Authentication Framework Now Stable</title>
      <dc:creator>Evgenii S.</dc:creator>
      <pubDate>Tue, 07 Oct 2025 17:02:01 +0000</pubDate>
      <link>https://dev.to/enjaku4/veri-v10-minimal-rails-authentication-framework-now-stable-3f6b</link>
      <guid>https://dev.to/enjaku4/veri-v10-minimal-rails-authentication-framework-now-stable-3f6b</guid>
      <description>&lt;p&gt;After months of development and testing, &lt;a href="https://github.com/enjaku4/veri" rel="noopener noreferrer"&gt;Veri&lt;/a&gt; has reached its first stable release!&lt;/p&gt;

&lt;p&gt;For those unfamiliar, Veri is a minimal authentication framework for Rails that gives you building blocks for custom authentication flows. No generated controllers, views, and mailers, no forced business logic - just the core mechanics of secure authentication that you can build upon.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What’s included:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Cookie-based authentication with database-stored sessions&lt;/li&gt;
&lt;li&gt;Multiple password hashing algorithms (argon2, bcrypt, pbkdf2, scrypt)&lt;/li&gt;
&lt;li&gt;Granular session management and control&lt;/li&gt;
&lt;li&gt;User impersonation for admin features&lt;/li&gt;
&lt;li&gt;Account lockout functionality&lt;/li&gt;
&lt;li&gt;Multi-tenancy support&lt;/li&gt;
&lt;li&gt;Return path handling&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Who it’s for:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Developers who want control over their authentication flow. If you’ve ever felt constrained by Devise or similar gems, Veri might be your cup of tea.&lt;/p&gt;

&lt;p&gt;Check it out &lt;a href="https://github.com/enjaku4/veri" rel="noopener noreferrer"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Happy coding!&lt;/p&gt;

</description>
      <category>rails</category>
      <category>ruby</category>
      <category>webdev</category>
      <category>security</category>
    </item>
    <item>
      <title>Veri v0.4.0 – Multi-Tenancy Update for the Rails Authentication Gem</title>
      <dc:creator>Evgenii S.</dc:creator>
      <pubDate>Fri, 12 Sep 2025 21:48:00 +0000</pubDate>
      <link>https://dev.to/enjaku4/veri-v040-multi-tenancy-update-for-the-rails-authentication-gem-3nb2</link>
      <guid>https://dev.to/enjaku4/veri-v040-multi-tenancy-update-for-the-rails-authentication-gem-3nb2</guid>
      <description>&lt;p&gt;We just released &lt;a href="https://github.com/enjaku4/veri" rel="noopener noreferrer"&gt;Veri v0.4.0&lt;/a&gt;, introducing multi-tenancy support. Now you can isolate authentication sessions per tenant, whether that’s a subdomain or a model representing an organization.&lt;/p&gt;

&lt;p&gt;This update also adds several useful scopes and renames a couple of methods.&lt;/p&gt;

&lt;p&gt;⚠️The gem is still in early development, so expect breaking changes in minor versions until v1.0!&lt;/p&gt;

&lt;p&gt;Check it out here: &lt;a href="https://github.com/enjaku4/veri" rel="noopener noreferrer"&gt;https://github.com/enjaku4/veri&lt;/a&gt;&lt;/p&gt;

</description>
      <category>rails</category>
      <category>ruby</category>
      <category>webdev</category>
      <category>news</category>
    </item>
    <item>
      <title>Introducing Veri – Minimal Cookie-Based Authentication for Rails</title>
      <dc:creator>Evgenii S.</dc:creator>
      <pubDate>Wed, 25 Jun 2025 06:32:48 +0000</pubDate>
      <link>https://dev.to/enjaku4/introducing-veri-minimal-cookie-based-authentication-for-rails-51co</link>
      <guid>https://dev.to/enjaku4/introducing-veri-minimal-cookie-based-authentication-for-rails-51co</guid>
      <description>&lt;p&gt;&lt;a href="https://github.com/enjaku4/veri" rel="noopener noreferrer"&gt;https://github.com/enjaku4/veri&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Veri is a new minimalistic authentication framework for Rails built around granular session management. Unlike full-stack solutions, Veri doesn’t impose business logic or provide pre-built views and controllers. It focuses on secure authentication primitives with detailed session control and gives you the building blocks for custom authentication flows.&lt;/p&gt;

&lt;p&gt;Key features:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Database-stored sessions with detailed tracking info&lt;/li&gt;
&lt;li&gt;Sessions can be listed and terminated selectively&lt;/li&gt;
&lt;li&gt;Built-in user impersonation for admin features&lt;/li&gt;
&lt;li&gt;Secure password storage with multiple hashing algorithms&lt;/li&gt;
&lt;li&gt;Return path handling&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;It’s functional and ready to try, although still in early development with potential breaking changes before v1.0.&lt;/p&gt;

</description>
      <category>rails</category>
      <category>ruby</category>
      <category>news</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Grepfruit 3.0.0 Released</title>
      <dc:creator>Evgenii S.</dc:creator>
      <pubDate>Mon, 16 Jun 2025 19:23:12 +0000</pubDate>
      <link>https://dev.to/enjaku4/grepfruit-300-release-5d46</link>
      <guid>https://dev.to/enjaku4/grepfruit-300-release-5d46</guid>
      <description>&lt;p&gt;Just released version 3.0.0 of &lt;a href="https://github.com/enjaku4/grepfruit" rel="noopener noreferrer"&gt;Grepfruit&lt;/a&gt;, a Ruby gem for searching text patterns in files with enhanced output.&lt;/p&gt;

&lt;p&gt;This version adds:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Parallel processing&lt;/strong&gt; using Ractors&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;JSON-formatted output&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;There are breaking changes from 2.x, so check the changelog when upgrading.&lt;/p&gt;

&lt;p&gt;Repository: &lt;a href="https://github.com/enjaku4/grepfruit" rel="noopener noreferrer"&gt;https://github.com/enjaku4/grepfruit&lt;/a&gt;&lt;/p&gt;

</description>
      <category>ruby</category>
      <category>cli</category>
    </item>
    <item>
      <title>Rabarber v5: Cleaner, Leaner, and More Stable</title>
      <dc:creator>Evgenii S.</dc:creator>
      <pubDate>Tue, 20 May 2025 13:03:11 +0000</pubDate>
      <link>https://dev.to/enjaku4/rabarber-v5-cleaner-leaner-and-more-stable-1fhc</link>
      <guid>https://dev.to/enjaku4/rabarber-v5-cleaner-leaner-and-more-stable-1fhc</guid>
      <description>&lt;p&gt;It’s been a while since our last major announcement - now, we’re happy to share &lt;a href="https://github.com/enjaku4/rabarber" rel="noopener noreferrer"&gt;Rabarber version 5&lt;/a&gt;, a new release of our role-based authorization gem for Rails.&lt;/p&gt;

&lt;p&gt;This release focuses on cleaning up and simplifying. We dropped legacy features that only added complexity, bringing Rabarber closer to what it was always meant to be. We also added more granular authorization controls and resolved a number of issues and design flaws along the way.&lt;/p&gt;

&lt;p&gt;With many improvements and fixes accumulated over the past year, upgrading is highly recommended. There are breaking changes, so be sure to check the &lt;a href="https://github.com/enjaku4/rabarber/discussions/77" rel="noopener noreferrer"&gt;migration guide&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Find the repo and docs here: &lt;a href="https://github.com/enjaku4/rabarber" rel="noopener noreferrer"&gt;https://github.com/enjaku4/rabarber&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Happy coding!&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Rabarber Developers&lt;/em&gt;&lt;/p&gt;

</description>
      <category>rails</category>
      <category>ruby</category>
      <category>gem</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Kreds v1 is out</title>
      <dc:creator>Evgenii S.</dc:creator>
      <pubDate>Mon, 07 Apr 2025 21:54:32 +0000</pubDate>
      <link>https://dev.to/enjaku4/kreds-v1-is-out-4je4</link>
      <guid>https://dev.to/enjaku4/kreds-v1-is-out-4je4</guid>
      <description>&lt;p&gt;It provides a safer, cleaner interface for accessing Rails credentials with strict error handling, optional fallback to environment variables, and support for environment-specific structures.&lt;/p&gt;

&lt;p&gt;This release finalizes the API, improves error clarity, and adds a few practical tools.&lt;/p&gt;

&lt;p&gt;More info: &lt;a href="https://github.com/enjaku4/kreds" rel="noopener noreferrer"&gt;https://github.com/enjaku4/kreds&lt;/a&gt;&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>rails</category>
      <category>ruby</category>
      <category>gem</category>
    </item>
    <item>
      <title>Kreds – the Missing Shorthand for Rails Credentials Access</title>
      <dc:creator>Evgenii S.</dc:creator>
      <pubDate>Mon, 10 Mar 2025 10:05:25 +0000</pubDate>
      <link>https://dev.to/enjaku4/kreds-the-missing-shorthand-for-rails-credentials-access-eaf</link>
      <guid>https://dev.to/enjaku4/kreds-the-missing-shorthand-for-rails-credentials-access-eaf</guid>
      <description>&lt;p&gt;Managing Rails application credentials can sometimes lead to hard-to-debug issues when keys are mistyped or values are unexpectedly blank. Kreds is a small gem that provides a shorthand for fetching credentials, raising clear errors for missing keys or empty values. More details here: &lt;a href="https://github.com/enjaku4/kreds" rel="noopener noreferrer"&gt;https://github.com/enjaku4/kreds&lt;/a&gt;&lt;/p&gt;

</description>
      <category>rails</category>
      <category>ruby</category>
      <category>webdev</category>
      <category>gem</category>
    </item>
    <item>
      <title>Grepfruit – A Ruby Gem for User-Friendly Regex Search in Files</title>
      <dc:creator>Evgenii S.</dc:creator>
      <pubDate>Fri, 07 Mar 2025 09:12:08 +0000</pubDate>
      <link>https://dev.to/enjaku4/grepfruit-a-ruby-gem-for-user-friendly-regex-search-in-files-5glj</link>
      <guid>https://dev.to/enjaku4/grepfruit-a-ruby-gem-for-user-friendly-regex-search-in-files-5glj</guid>
      <description>&lt;p&gt;Grepfruit is a Ruby gem for searching text patterns in files with colorized output, making the process more user-friendly than standard tools like grep. It offers options to exclude files or directories, truncate output, and include hidden files. Originally created for CI/CD pipelines to search for TODO comments in Rails apps, it’s flexible for a wide range of use cases. Check it out here: &lt;a href="https://github.com/enjaku4/grepfruit" rel="noopener noreferrer"&gt;https://github.com/enjaku4/grepfruit&lt;/a&gt;&lt;/p&gt;

</description>
      <category>ruby</category>
      <category>gem</category>
      <category>cli</category>
    </item>
  </channel>
</rss>
