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.

Published
Author
user-image
Syed
Shared Context in RSpec

Shared Context: A shared context in RSpec is a way to define common setup code that can be reused across multiple test examples or groups. Instead of duplicating setup code, we define it once in a shared context and include it wherever needed. It helps keep our tests DRY.


Ruby

RSpec.shared_context "user and post setup", shared_context: :metadata do
  let(:user) { User.create(name: "Alice") }
  let(:post) { Post.create(title: "First Post", user: user) }
end

RSpec.describe "Using shared context in tests" do
  include_context "user and post setup"

  it "has a user with a name" do
    expect(user.name).to eq("Alice")
  end

  it "has a post with a title" do
    expect(post.title).to eq("First Post")
  end
end


In the example, the shared context user and post setup defines let variables for a user and a post.
By including the shared context with include_context, we gain access to those let variables in the test examples.

#rspec #rubyonrails
Published
Author
user-image
Vaibhav Yadav
Senior System Analyst
Using DISTINCT ON in PostgreSQL

When using DISTINCT ON in PostgreSQL, the columns specified in the DISTINCT ON clause must appear first in the ORDER BY clause and in the same order. This is a requirement to ensure PostgreSQL knows how to determine the "first" row for each distinct group.

For example:

Code

SELECT DISTINCT ON (user_id, event_name) id, user_id, event_name, inquiry_id, created_at
FROM public.persona_inquiry
ORDER BY user_id, event_name, created_at DESC;


Key points:
DISTINCT ON (user_id, event_name) selects the first row for each unique (user_id, event_name) combination.
ORDER BY user_id, event_name ensures that the sorting starts with the same columns as the DISTINCT ON clause.
• Additional columns in ORDER BY (like created_at DESC) determine which row to pick when there are duplicates.
Mistakenly not matching the DISTINCT ON columns with the start of the ORDER BY clause will result in an error:
SELECT DISTINCT ON expressions must match initial ORDER BY expressions.

#postgres #sql #database
Published
Author
user-image
Satya
ActiveSupport::CurrentAttributes provides a thread-isolated attributes singleton, perfect for request-specific data like current user, role, or locale.
create a current.rb in models directory and add the attributes we want to set

Ruby

class Current < ActiveSupport::CurrentAttributes
  attribute :role
end


then in application controller we can set it like this

Ruby

class ApplicationController < ActionController::Base  
  before_action :set_current_attributes

  def set_current_attributes
    Current.role = session[:role]
    // ... other attributes
  end
end


now in your application we can directly access and use like Current.role

#CU6U0R822 #rails-current-attributes
Published
Author
user-image
Codemancers
Mise

Mise is a fast, lightweight (thanks to Rust :happy_pepe:), language agnostic version manager that can be used instead of having separate language based version managers like rbenv for Ruby, npm for Node.js and Pyenv for Python etc.

Installing a Ruby version globally is as simple as follows:

Code

mise use -g ruby@3


Installing mise is as easy as following in MacOS

Code

curl https://mise.run | sh


Proceed with following to configure the Shell Initialisation

Code

echo 'eval "$(~/.local/bin/mise activate)"' >> ~/.zshrc


Reload the shell configuration changes in current tab

Code

source ~/.zshrc


#mise #ruby-version-manager #version-manager #C04HPTKNZ8R #ruby #python #CCT1JMA0Z
Published
Author
user-image
Nived
mattr_accessor is a Rails utility method that creates a class-level accessor for a variable.
When we define mattr_accessor for a variable, it creates
1. A getter method for the class.
2. A setter method for the class.
Eg:

Ruby

class MyClass
  mattr_accessor :my_variable
end


This is equivalent to:

Ruby

class MyClass
  @my_variable = nil

  def self.my_variable
    @my_variable
  end

  def self.my_variable=(value)
    @my_variable = value
  end
end


It also works on module-level classes, which makes it particularly useful for defining global configuration in gems.

#CU6U0R822
Published
Author
user-image
Ayush
accepts_nested_attributes_for is a Rails method that allows you to easily manage the creation, updating, and destruction of associated models through the parent model's attributes. This is particularly useful when you have nested forms or when you want to handle multiple models in a single operation (e.g., creating or updating a User and its associated Profile in one form submission).


Ruby

class User < ApplicationRecord
  has_one :profile
  accepts_nested_attributes_for :profile
end


Given the User model has a has_one :profile association, and you want to create or update a User and their Profile at the same time, you can use accepts_nested_attributes_for to pass attributes for both models:

Ruby

user_params = {
  name: "John Doe",
  profile_attributes: { bio: "Developer", age: 30 }
}

user = User.create(user_params)


In this example, Rails will create both a new User and a new Profile with the attributes provided in profile_attributes.
#CU6U0R822
Published
Author
user-image
Syed
When working with paginated data in Ruby on Rails, we might encounter situations where we need to paginate an array rather than an Active Record collection. The pagy gem provides an efficient and flexible way to handle pagination, and it includes an extras/array feature specifically for arrays.

Require the Pagy Extras Array:

Ruby

# config/initializers/pagy.rb

require "pagy/extras/array"


And then use the pagy_array method to paginate your array in the controller

Ruby

def index
 // some code
 @pagy, @purchase_order_attachments = pagy_array(orders_with_attachments, items: params[:limit] || 10)
end


#rubyonrails #pagination #pagy
Published
Author
user-image
Adithya Hebbar
System Analyst
In Python, dir() lists the attributes and methods of an object, such as a class or instance.

Example:

Python

class MyClass:
    class_variable = "Class Variable"

    def __init__(self):
        self.instance_variable = "Instance Variable"

    def my_method(self):
        pass

obj = MyClass()
print(dir(obj))


Output:
dir(obj) shows a list of attributes (class_variable, instance_variable) and methods (my_method), along with special methods (e.g., __init__). It helps explore what’s available in an object.
Published
Author
user-image
Nisanth
Test SSH connection detailed logs to debug #ssh #CCTJN6PK4

Code

ssh -vT "[email protected]"


This will output detailed logs
Published
Author
user-image
Ashwani Kumar Jha
Senior System Analyst
Definite Assignment Checks in TypeScript 5

• Before TypeScript 5:

TypeScript

let value: string;
console.log(value); // TS4.x: This was allowed but could lead to runtime undefined


• After TypeScript 5:

TypeScript

let value: string;
console.log(value); // TS5.x: Error - Variable 'value' is used before being assigned

// To fix, either initialize:
let value = "initial";

// Or use definite assignment assertion:
let value!: string;


• The ! is a promise to TypeScript that we'll assign a value before using it
• Use of ! should be avoided as it bypasses TypeScript's safety checks
Published
Author
user-image
Nived
When working with routes in a Rails application that includes an engine, route references need to be scoped appropriately based on where they are being called:
• Referencing engine routes from outside the engine: Prefix the route with the engine's name. For example, use engine_name.some_route_path (e.g., rapidfire.surveys_path) to access routes within the engine.
• Referencing routes from another engine: Use the other engine's name as a prefix, similar to referencing routes from outside.
This naming ensures the correct routing context and prevents conflicts when multiple engines or the main application define similar paths.

#CU6U0R822 #routes
Published
Author
user-image
Nived
Form Objects in Rails
Form objects are a pattern that is used to encapsulate logic for managing and validating form data. They act as an intermediary between the view and the model layer, they simplify the handling of complex forms, particularly when working with complex forms that don't map to a single active record model.
Why use form objects?
In typical rails applications, forms are directly tied to active record models. This is ok when the forms are simple, but this can cause problem when complexity increases such as,
when forms interact with multiple models
In these kind of scenarios, we can encapsulate the corresponding logic into a single class which acts like an active record model which is easier to maintain.

Example form object
app/forms/route_request_form.rb

Ruby

class UserProfileForm
  include ActiveModel::Model

 # Attributes accessible for the form object.
  attr_accessor :user_name, :email, :profile_bio, :profile_age

  validates :user_name, :email, presence: true
  validates :profile_age, numericality: { only_integer: true, greater_than: 0 }

  def save
    return false unless valid?
    
    #a single transaction for multiple operations
    ActiveRecord::Base.transaction do
      user = User.create!(name: user_name, email: email)
      user.create_profile!(bio: profile_bio, age: profile_age)
    end

    true # Return true if all operations succeed.
  rescue ActiveRecord::RecordInvalid
    false # Return false if the save process fails.
  end
end


Using it in controller

Ruby

class UsersController < ApplicationController
  def new
    @form = UserProfileForm.new
  end

  def create
    @form = UserProfileForm.new(user_profile_form_params)

    if @form.save
      redirect_to root_path, notice: "User created successfully!"
    else
      render :new, status: :unprocessable_entity
    end
  end

  private

  def user_profile_form_params
    params.require(:user_profile_form).permit(:user_name, :email, :profile_bio, :profile_age)
  end
end




#ruby_on_rails #form_objects
Published
Author
user-image
Codemancers
*
*Convert .pem certificate into .pfx

To convert a .pem certificate to .pfx, follow these steps:
1. Ensure you have OpenSSL installed.
2. Prepare the required files:
.pem certificate file (certificate.pem)
◦ Private key file (privatekey.pem)
◦ (Optional) CA chain file (ca-chain.pem)
3. Run the following command to create the .pfx file:

Code

openssl pkcs12 -export -out certificate.pfx -inkey privatekey.pem -in certificate.pem -certfile ca-chain.pem


4. When prompted, enter a password to secure the .pfx file.
5. Verify the .pfx file using:

Code

openssl pkcs12 -info -in certificate.pfx


This process combines the certificate, private key, and CA chain (if provided) into a .pfx file, which is commonly used for secure applications like Windows servers or browser-based authentication.
#Certificates #SSL&TLS
Published
Author
user-image
Codemancers
Convert .pem certificate into .pfx
To convert a .pem certificate to .pfx, ensure you have OpenSSL installed and have your .pem certificate file, private key file, and optionally a CA chain file ready.
Use the command:
Published
Author
user-image
Nitturu
Optimizing Validations with Caching

When we have a Member model where each user has a specific number of coins. When performing operations like capturing or deducting coins, we want to validate:

1. The user exists or not.
2. The user has enough coins to complete the operation.
The basic validation will look like this (with dry-validation gem)


Ruby

class CoinsValidator < Dry::Validation::Contract
  params do
    required(:user).filled(:integer)
    required(:coins).filled(:integer, gt?: 0)
  end

  rule(:user) do
    member = Member.find_by(unique_id: value) // querying database for member details
    key.failure("does not exist") if member.nil?
  end

  rule(:coins, :user) do
    member = Member.find_by(unique_id: values[:user]) // querying database for member details
    if member && member.coins < values[:coins]
      key(:coins).failure("are insufficient")
    end
  end
end


But the problem here is, We query the database twice to fetch the same Member object once in the :user rule and again in the :coins rule. This redundant querying increases database load and slows down validation, especially in high-traffic applications.

To avoid redundant queries, we can cache the Member object using the values hash provided by the dry-validation gem. The values hash allows us to store intermediate results, making them accessible to other validation rules.
The optimized code looks like this:


Ruby

class CoinsValidator < Dry::Validation::Contract
  params do
    required(:user).filled(:integer)
    required(:coins).filled(:integer, gt?: 0)
  end

  rule(:user) do
    values[:member] = Member.find_by(unique_id: value)  // Caching the member object
    key.failure("does not exist") if values[:member].nil?
  end

  rule(:coins) do
    member = values[:member]  // accessing the cached Member from values[:member] rather than querying the database again.
    if member && member.coins < value
      key.failure("are insufficient")
    end
  end
end


#ruby on rails
Published
Author
user-image
Amber Srivastava
Mocking Timers for Controlled Testing

If your code uses setTimeout or setInterval, Jest's timer mocking lets you fast-forward time.
Example: Using jest.useFakeTimers()


Code

jest.useFakeTimers();

test("delayed greeting is sent after 3 seconds", () => {
  const callback = jest.fn();

  setTimeout(() => callback("Hello!"), 3000);
  jest.runAllTimers();

  expect(callback).toHaveBeenCalledWith("Hello!");
});


#CCT1JMA0Z # testing #jest
Published
Author
user-image
Syed
In Ruby, attr_reader and attr_accessor are used to create getter and setter methods for class attributes. These are part of a group of methods (attr_* methods) that make it easier to create getter and setter methods for class attributes.

attr_reader: Creates a getter method, allowing read-only access to an instance variable.

Ruby

class Person
  attr_reader :name

  def initialize(name)
    @name = name
  end
end

person = Person.new("Sibtain")
puts person.name  # Outputs: Sibtain


attr_accessor: Creates both getter and setter methods, allowing read and write access to an instance variable.

Ruby

class Person
  attr_accessor :name

  def initialize(name)
    @name = name
  end
end

person = Person.new("Sibtain")
puts person.name  # Outputs: Sibtain

person.name = "John"
puts person.name  # Outputs: John


Furthermore, using attr_reader and attr_accessor promotes encapsulation by controlling how the attributes of a class are accessed and modified.

#ruby #rubyonrails
Published
Author
user-image
Amber Srivastava
------------------------- useFieldArray hook in react-hook-form -------------------------
The useFieldArray hook is part of react-hook-form and is used for handling dynamic fields in forms, such as arrays of inputs that can be added or removed dynamically.
For example, if you have a list of items (like questions, tasks, or other fields) that can be added, removed, or reordered during form submission, useFieldArray is the ideal solution to manage that dynamic behaviour without manually managing the state of each individual field.

How useFieldArray works:
fields: An array of objects, where each object represents a field in the array.
append: A function to add new fields to the array.
remove: A function to remove fields from the array.
update: A function to update an individual field in the array.
Example:-

JavaScript

import { useForm, useFieldArray } from "react-hook-form";

function DynamicForm() {
  const { register, control, handleSubmit, formState: { errors } } = useForm({
    defaultValues: {
      questions: [{ question: "" }],
    },
  });

  // UseFieldArray to handle the questions array dynamically
  const { fields, append, remove } = useFieldArray({
    control,
    name: "questions",  // Name of the array in the form's state
  });

  const onSubmit = (data: any) => {
    console.log(data); // Submitting form data with dynamic fields
  };

  return (
    <form onSubmit={handleSubmit(onSubmit)}>
      {fields.map((item, index) => (
        <div key={item.id}>
          <input
            {...register(`questions.${index}.question`)}  // Register each question dynamically
            defaultValue={item.question}  // Set default value for each item in the array
          />
          {errors.questions?.[index]?.question && (
            <span>{errors.questions[index]?.question.message}</span>
          )}
          <button type="button" onClick={() => remove(index)}>Remove</button>
        </div>
      ))}
      
      <button type="button" onClick={() => append({ question: "" })}>
        Add Question
      </button>

      <button type="submit">Submit</button>
    </form>
  );
}


Key Points:
1. name: The name prop in useFieldArray points to the field array in your form state (in this case, questions).
2. fields: This array holds the current data of the dynamic fields. Each item corresponds to a field in the form array.
3. append: This method is used to add a new item to the array. You can pass the new data for the item when appending.
4. remove: This method is used to remove an item by its index.
When to use useFieldArray:
Dynamic Forms: When you have a form where the number of fields can change over time, such as adding/removing questions, tasks, team members, etc.
Nested Fields: When you have an array of objects (e.g., an array of questions, where each question has a title and description).
Advantages:
• It reduces the need for manual state management when adding/removing fields.
• It integrates seamlessly with react-hook-form to handle validations and form submission.
• It improves performance by avoiding unnecessary re-renders when fields are added or removed.
#CCT1JMA0Z #useForm #react-hook-form
Published
Author
user-image
Ayasha
Slack's chat.deleteScheduledMessage API allows you to delete messages that were scheduled using chat.scheduleMessage but have not yet been sent.

JavaScript

const response = await slackClient.chat.deleteScheduledMessage({
  channel: channelId, {// ID of the channel where the message was scheduled }
  scheduled_message_id: scheduledMessageId, {// ID of the scheduled message to delete}
});


#slack #api
Published
Author
user-image
Nitturu
How to write tests for external APIs?

This can be achieved using the gem "webmock".

Using webmock we will similate the external API call and use mockdata as the response to the APIs.

step1: install the gem "webmock"
step2: add the following lines to rails helper.

Ruby

require 'webmock/webmock_api.rb'

config.before(:each) do
    stub_request(:any, /domain_name/).to_rack(WebmockApi
end


step3: create mock data responses for the APIs inside fixtures folder in spec.

member_api_success.json

Ruby

# spec/fixtures/member_api_success.json
[
  {
    "id": 1,
    "name": "John Doe",
    "email": "[email protected]",
    "phone": "123-456-7890",
    "membership_type": "Gold",
    "status": "active"
  },
  {
    "id": 2,
    "name": "Jane Smith",
    "email": "[email protected]",
    "phone": "987-654-3210",
    "membership_type": "Silver",
    "status": "inactive"
  }
]


step4: inside spec create webmock file. Inside webmock create webmock_api.rb file. In this file we will simulate the responses for the API using mock data we have created.

Ruby

class WebmockApi
  SPEC_FIXTURES_PATH = 'spec/fixtures'.freeze
  MEMBERS_SUCCESS = File.read("#{SPEC_FIXTURES_PATH}/members_api_success.json").freeze
  POSTS_SUCCESS = File.read("#{SPEC_FIXTURES_PATH}/posts_api_success.json").freeze
  ERROR = File.read("#{SPEC_FIXTURES_PATH}/error.json").freeze

  def self.call(env)
    new.call(env)
  end

  def call(env)
    action = env['REQUEST_METHOD']
    path = env['PATH_INFO']
    params = env['QUERY_STRING']

    case path
    when '/external_members_api_path'
      params.include?('test_user') ? [ 200, {}, [ MEMBERS_SUCCESS ] ] : [ 500, {}, [ ERROR ] ]
    when '/external_post_api_path'
      params.include?('new_post') ? [ 200, {}, [ POSTS_SUCCESS ] ] : [ 500, {}, [ ERROR ] ]
    end
  end
end


step5: write the test cases for the APIs in requests folder.

Ruby

require 'rails_helper'
require 'webmock/rspec'

RSpec.describe "Members", type: :request do
  describe "GET /members_search_path" do
    context "when the members API call is successful" do
      it "returns member details from the API" do
        get "/external_members_api_path", params: { member: "test_user" }

        expect(response).to have_http_status(:ok)
        user = response.parsed_body["member"]
        expect(["id"]).to eq("123456")
        expect(user["name"]).to eq("abc")
      end
    end
    
    context "when the members API call is successful" do
      it "returns error message from the API" do
        get "/external_members_api_path", params: { member: "unknown_user" }

        expect(response).to have_http_status(:ok)
        expect(response).to have_http_status(:internal_server_error)
        error = response.parsed_body["error"]
        expect(error).to eq("Something went wrong")
      end
    end
  end
end


#ruby on rails

Showing page 6 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.