Skip to content

TILs

Fueling Curiosity, One Insight at a Time

At Codemancers, we believe every day is an opportunity to grow. This section is where our team shares bite-sized discoveries, technical breakthroughs and fascinating nuggets of wisdom we've stumbled upon in our work.

  1. Adithya HebbarSystem Analyst
    Here is how to generate robots.txt in Next.Js - App Router. Add a robots.js or robots.ts file in your app directory

    Code

    import type { MetadataRoute } from 'next'
     
    export default function robots(): MetadataRoute.Robots {
      return {
        rules: {
          userAgent: '*',
          allow: '/',
          disallow: '/private/',
        },
      }
    }


    This will add or generate a robots.txt file that matches the https://en.wikipedia.org/wiki/Robots.txt#Standard|Robots Exclusion Standard in the root of app directory to tell search engine crawlers which URLs they can access on your site.

    #js #nextjs #seo
  2. We can generate a UUID in Rails using SecureRandom.uuid without needing any gem
    #CU6U0R822
  3. GiritharanSystem Analyst
    Managing Global Attributes with ActiveSupport::CurrentAttributes in Rails

    In Rails, ActiveSupport::CurrentAttributes simplifies the process of storing global, thread-safe data like Current.user or Current.account during requests or jobs. It should be limited to top-level globals, such as user and request details, which are needed across all actions.

    In controllers, Rails automatically resets Current between requests, so we don’t need to manually clear it. However, In Active Jobs, we need to manually reset Current after each job to prevent data from leaking between job executions. We achieve this using the after_perform callback.

    Code Example:
    *app/models/current.rb*:


    Ruby

    class Current < ActiveSupport::CurrentAttributes
      attribute :user, :account, :request_id
    end


    app/jobs/my_job.rb:


    Ruby

    class MyJob < ApplicationJob
      after_perform :clear_current_attributes
    
      def perform(params)
        set_current_attributes(params[:user_id])
      end
    
      private
    
      def set_current_attributes(user_id)
        Current.user = User.find_by(id: user_id)
        Current.request_id = SecureRandom.uuid
      end
    
      def clear_current_attributes
        Current.reset
      end
    end


    In summary: Rails handles resetting Current for controllers, but for jobs, we must manually reset it after each job to avoid data leakage.

    #current #currentAttributes #CU6U0R822
  4. Aman SuhagSystem Analyst
    In TypeScript, a tuple is a typed array with a fixed number of elements, where each element may have a different type. Unlike regular arrays, which can hold any number of elements of the same type, tuples define a specific sequence of element types and their corresponding positions.
    Key Characteristics of Tuples:
    1. Fixed Length: The number of elements in a tuple is fixed. You must specify how many elements the tuple can contain.
    2. Different Types: Each element in a tuple can be of a different type. The type for each position is defined.
    3. Access by Index: Elements are accessed by their index, just like regular arrays, but the types of the elements at each index are known and enforced by the type system.
    let user: [string, number?] = ["Alice"]; // number is optional
    #typescript #tuple
  5. the fallbackData parameter in useSWR to provide default data for your fetch request. This is super useful when you want to display initial data while waiting for the network request to resolve. The fallback data will be used as the initial value for the data until the fetcher returns the actual data.


    JavaScript

    const {
      data,
      mutate,
      error,
    } = useSWR(endpoint, fetcherFunction, {
      fallbackData: initialData,
    });


    #swr #hook
  6. Soniya Rayabagi
    "Adding a User to the Docker Group on Ubuntu"
    1. sudo groupadd docker # Create the Docker group if it doesn't exist
    2. sudo usermod -aG docker $USER # Adds the current user to the 'docker' group.
    3. newgrp docker # Apply the new group membership
    4. docker run hello-world # Checks if the user can run Docker commands without sudo
    #Ubuntu #DevOps #Docker
  7. Amber Srivastava
    useFormContext hook

    The useFormContext hook is a part of react-hook-form and allows you to access form methods (such as setValue, getValues, etc.) from any component nested inside the FormProvider. This is useful when you want to manage the form state across deeply nested components without passing props down manually.

    Steps to Use useFormContext:
    1. Wrap your form with FormProvider: This allows any child component to access the form context via useFormContext.
    2. Access form methods using useFormContext: In your component, you can call useFormContext to access setValue, getValues, etc.
    Example
    1. In your main form component: Wrap your form with FormProvider and pass in useForm's returned values.

    Code

    import { useForm, FormProvider } from "react-hook-form";
    
    const FormComponent = () => {
      const methods = useForm();
    
      return (
        <FormProvider {...methods}>
          <form>
            {/* Now any nested component can use useFormContext */}
            <ChildComponent />
            {/* Submit button or other components */}
          </form>
        </FormProvider>
      );
    };


    2. In your ChildComponent or any other component: Use useFormContext to access the form methods like setValue or getValues.

    Code

    import { useFormContext } from "react-hook-form";
    
    const ChildComponent = () => {
      const { setValue } = useFormContext(); // useFormContext gives access to all form methods
    
      return (
        <div>
          {/* Dropdown logic */}
        </div>
      );
    };


    #useForm #CCT1JMA0Z
  8. GiritharanSystem Analyst
    Managing Jobs in SolidQueue with Rails Console

    • SolidQueue::RecurringExecution.all : You can find and manage recurring jobs with this query.
    • SolidQueue::ReadyExecution.all: Use this query to identify jobs that are ready to run but haven’t started yet.
    • SolidQueue::BlockedExecution.all: Find jobs that are blocked and waiting for conditions to be met before execution.
    • SolidQueue::ClaimedExecution.all: Check jobs that have been claimed by workers but are still in progress.
    • SolidQueue::FailedExecution.all: Use this to track jobs that failed during execution.
    • SolidQueue::ScheduledExecution.all: Find jobs that are scheduled for future execution.
    • SolidQueue::Job.where(finished_at: nil): Query to get jobs that are still running or haven’t finished yet.
    #activejob #solidqueue #queriesforsolidqueue #CU6U0R822
  9. Adithya HebbarSystem Analyst
    Here’s how to update the most recent commit with new changes:

    git commit --amend --no-edit command allows you to modify the most recent commit without changing its commit message.

    • The --amend flag updates the previous commit with the new changes.
    • The --no-edit option keeps the existing commit message unchanged.
    After amending the commit, if it has already been pushed to the remote repository, you’ll need to force push the changes using: git push -f

    #git #git-commit
  10. Aman SuhagSystem Analyst
    Symbols shown in build logs for routes specifies-
    ƒ: A dynamic function, typically an API route, that runs on the server and is not statically exported.
    ○: A statically generated (SSG) page, built once during the build process.
    ●: A dynamically generated (SSR) page, built at request time.
    #build
  11. GiritharanSystem Analyst
    Rails Association Callbacks

    Rails association callbacks let you hook into the lifecycle events of an associated collection. These callbacks are triggered when objects are added to or removed from the collection.

    Available Callbacks:
    - before_add: Invoked before an object is added to the collection.
    - after_add: Invoked after an object is added to the collection.
    - before_remove: Invoked before an object is removed from the collection.
    - after_remove: Invoked after an object is removed from the collection.

    #associationcallbacks #callbacks #CU6U0R822
  12. "Search-as-You-Type" in Rails with Turbo Frames and Stimulus

    Making the search box more interactive can be achieved with simple steps:

    We could do this without Turbo by submitting the form whenever an input event occurs, right? No. In that case, on each input, the form gets submitted, and the input field loses focus. This is where Turbo Frames come into play. For this scenario, we need Turbo to reload only the content we want to update while leaving the rest of the page as it is.

    For this, we define which part we want to reload based on our search by wrapping that particular section inside a turbo_frame_tag and targeting that Turbo Frame from the search form.

    Sample search form:


    Ruby

    <%= form_with(
      url: search_path, method: :get,
      data: { turbo_frame: "frame_id", turbo_action: "advance", controller: "search", action: "input->search#submit" }
    ) do |f| %>
      <%= f.search_field field_name, placeholder: placeholder, value: params %>
    <% end %>


    turbo_frame : Points to the specific Turbo Frame we want to update with the search results. It allows us to reload only the content within this frame without affecting the rest of the page.
    turbo_action : Defines the behavior of the Turbo request. In this case, it is set to "advance," which means the URL is appended to the previous ones. This allows users to navigate back to previous searches using the browser's back button, maintaining the search history. There are other actions like "restore", "pop" as well.

    Example:


    Ruby

    <%= turbo_frame_tag "search_results" do %>
           <div id="results"></div>  #This will contain the search results
    <% end %>


    ( We will give data : { turbo_frame: "search_results" } in this case )

    In this way, when a fetch occurs from the search form, only the part inside the turbo_frame_tag is reloaded. The rest of the page remains untouched, and the form won't lose focus.

    For optimization, we can add debouncing also, which can be done in the Stimulus controller.

    #RubyOnRails #turbo #turbo_frames
  13. Fastest way to put website on internet:

    Using Ngrok we can do that easily.

    step1: install Ngrok

    step2: create account in Ngrok website (for AUTHTOKEN)

    step3: run the command in the terminal - ngrok authtoken YOUR_AUTHTOKEN

    step4: add the regex in config/environment/development.rb



    Code

    Rails.application.configure do
        # Other configurations...
        
        # Add your Ngrok URL to the list of allowed hosts 
        config.hosts << /[a-z0-9\\-]+\\.ngrok-free\\.app/
    end



    step5: start the server and open new terminal then in the project directory run the command ngrok http 3000 . Where 3000 is port number in which localhost is running.

    step6: ngrok will give us a link, with that link we can access the website.

    Ngrok is not only limited to rails. We can use with any framework.

    #CU6U0R822 #ngrok
  14. How to Create a Multi-Language Website in Rails

    Ruby on Rails comes with an integrated internationalization (I18n) framework that makes it simple to add multi-language support to your website.

    Create Locale Files

    You can define your translations using .yml files located in the config/locales directory.
    For example, if your website supports English and Hindi, you would create two files: en.yml and hi.yml.

    en.yml file:

    Ruby

    en:
        hello: "Hello"
        good_morning: "Good Morning %{name}"  # %{name} is used to pass dynamic parameters.
        rails: "Rails"


    hi.yml file:

    Ruby

    hi:
        hello: "नमस्ते"
        good_morning: "शुभ प्रभात  %{name}"
        rails: "रेल"


    Use Translations in Your Views

    You can use the t helper method to access translations in your views.


    Ruby

    <div><%= t("hello") %></div>   // normal usage
    <div><%= t("good_morning", name: t("rails")) %></div>  // Passing Dynamic Parameters.


    Language Switching via URL

    The language displayed will depend on the locale set in the URL. For example:
    • If the URL is https://localhost:3000/en, the English translation will be used.
    • If the URL is https://localhost:3000/hi, the Hindi translation will be used.
    #CU6U0R822 #multi-language
  15. A Dead Letter Queue is a special queue in message queue systems that holds messages (payload) that cannot be delivered to their intended recipients due to various reasons.
    These reasons can include:

    • Incorrect message formatting
    • Network errors
    • System failures
    • Application-level errors
    DLQs serve several important purpose.

    1. Message Preservation: They prevent loss of messages/payload that fail processing, allowing for later analysis or retry.
    2. System Stability: By isolating problematic messages/payload, DLQs prevent failures from affecting the main message flow.
    3. Debugging: DLQs provide a centralised location for developers to inspect and diagnose issues with failed messages.
    #deadletterqueue #queuemanagement
  16. Adithya HebbarSystem Analyst
    https://Fly.io|Fly.io release_command

    In https://Fly.io|Fly.io, the release_command is a special one-time command executed before deploying an app. It’s often used for tasks like running database migrations or other setup steps that need to happen before the app is fully launched. You can define it in your fly.toml file under the [deploy] section.

    Example:

    Python

    [deploy]
      release_command = "python manage.py migrate"


    This ensures your migrations or other essential pre-deploy tasks run seamlessly during the deployment process!

    #fly #db_migrations
  17. useFieldArray is a hook provided by React Hook Form that simplifies the process of managing dynamic form fields. It allows you to create forms where users can add, remove, move, and manipulate groups of inputs (or arrays of fields), like a list of tasks, addresses, or any repeatable form sections.
    Features :-
    1. Dynamic Fields Management
    2. Efficient Rendering
    Functions Provided by useFieldArray
    • append(): Adds a new item to the end of the field array.
    • prepend(): Adds a new item to the beginning of the field array.
    • remove(index): Removes a field at the specified index.
    • insert(index, value): Inserts a new field at a specific index.
    #react-hook #react-form #form
  18. Amber Srivastava
    To create a model in Prisma:
    1. Open the schema.prisma file.
    2. Define datasource and generator:

    Code

    datasource db {
      provider = "postgresql"
      url      = env("DATABASE_URL")
    }
    
    generator client {
      provider = "prisma-client-js"
    }


    Create the model:

    Code

    model Retro {
      id              String   @id @default(cuid())
      date            DateTime @default(now())   // Auto-fills current date
      scrumMasterId   String                        // For Scrum Master (User)
      slackChannel    String                        // Slack Channel input
      questions       String[]                      // Default retro questions
      projectId       Int       @relation(fields: [projectId], references: [id])
      project         Project   @relation(fields: [projectId], references: [id])
    }


    This creates the Retro table for your retrospectives.

    @id: Marks a field as the primary key.
    @default(): Sets a default value for a field.
    @relation(): Defines relationships between models.
    @unique: Ensures a field has unique values.
    String[]: Defines an array of strings.
    cuid(): Generates a unique ID.
    @updatedAt: Automatically updates the field with the current timestamp when data changes.

    #prisma #database #columns #model
  19. Aman SuhagSystem Analyst
    Mocking in Jest
    Jest provides several ways to mock:
    • jest.fn(): Creates a mock function that you can use instead of a real function.
    • jest.mock(): Mocks entire modules.
    • jest.spyOn(): Tracks calls to an existing method while optionally replacing its implementation.
    #jest #test #mock
  20. Ashwani Kumar JhaSenior System Analyst
    Async Local Storage in Node.js

    • Provides us a way to store and manage context-specific data across asynchronous operations without needing to pass it explicitly through function arguments.
    • Built on the async_hooks module, which tracks asynchronous resource lifecycle events.
    • We need to use asyncLocalStorage.run(store, callback) to create a new context.
    • Asynchronous operations initiated within this callback inherit that context.
    • Each context created with asyncLocalStorage.run() is unique and does not interfere with other contexts.
    • Common use cases can be maintaining custom context in our web app (e.g., request data, user ID...) across multiple layers (controllers, services, etc.), can help us with tracing how a request propagates through different async functions.
    • Automatically cleans up the context after the asynchronous operations are complete.
    • run(store, callback): Creates a new context and runs the callback with the provided store (like a Map or a primitive value).
    • Set a value: asyncLocalStorage.getStore().set('requestId', requestId);
    • Get a value: const requestId = asyncLocalStorage.getStore().get('requestId');

    JavaScript

    const http = require('node:http');
    const { AsyncLocalStorage } = require('node:async_hooks');
    const { v4: uuid } = require('uuid');
    
    const asyncLocalStorage = new AsyncLocalStorage();
    
    function logWithId(msg) {
      const requestId = asyncLocalStorage.getStore(); 
      console.log(`${requestId} - ${msg}`);
    }
    
    function serviceA() {
      logWithId('Service A log');
    }
    
    function serviceB() {
      logWithId('Service B log');
    }
    
    http.createServer((req, res) => {
      const requestId = uuid();
      asyncLocalStorage.run(requestId, () => { 
        logWithId('Request received');
        serviceA();
        serviceB();
        logWithId('All services called');
        res.end('Response sent');
      });
    }).listen(4040);
    
    http.get('https://localhost:4040');
    
    // Output:
    <generated-request-id> - Request received
    <generated-request-id> - Service A log
    <generated-request-id> - Service B log
    <generated-request-id> - All services called

Showing page 8 of 42

Your competitors are already using AI. The question is how fast you want to unlock the value.

  • Don't know where to start?

    AI is everywhere but it's unclear which investments will actually move your metrics and which are expensive experiments.

  • Your data isn't ready

    Most AI projects fail at the data layer. Pipelines, quality, access all need work before LLMs can deliver value.

  • Internal teams are stretched

    Your engineers are shipping product. They don't have capacity to also become AI specialists with production-grade experience.

  • Legacy systems block everything

    Aging, undocumented codebases make AI integration slow, risky, and expensive. They need to move first.

Don't worry. We've got you covered.

Start with the audit.

Book a free discovery call