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
Codemancers
Rails provides a https://api.rubyonrails.org/classes/ActiveRecord/TokenFor.html#method-i-generate_token_for|generates_token_for method on Active Record models, which can generate unique tokens for records — including support for expiration. This is useful for scenarios like creating unique unsubscribe links in emails. You can later retrieve a record using the generated token with the corresponding https://api.rubyonrails.org/classes/ActiveRecord/TokenFor/RelationMethods.html#method-i-find_by_token_for|find_by_token_for method.

The Rails Authentication generator utilizes this feature in its password reset flow. It uses https://api.rubyonrails.org/classes/ActiveModel/SecurePassword/ClassMethods.html#method-i-has_secure_password|has_secure_password, which by default enables password reset functionality for the user model. When you call the password_reset_token instance method on a user, it internally uses generates_token_for to generate a unique token. You can then find the user record later using find_by_password_reset_token.

By default, https://api.rubyonrails.org/classes/ActiveModel/SecurePassword/ClassMethods.html#method-i-has_secure_password|has_secure_password uses the password attribute, but you can customize this by specifying a different attribute via the attribute option. If you want to disable password reset functionality, you can pass reset_token: false to has_secure_password (it is enabled by default). Similarly, you can disable password confirmation validations by passing validations: false (validations are enabled by default).

#rubyonrails #ror #authentication #token #password
Published
Author
user-image
Codemancers
In recent versions of Rails, the default host for the test environment has changed from https://www.example.com|www.example.com to https://example.com|example.com. However, Capybara continues to use https://www.example.com|www.example.com in most cases, which can cause URL assertions in ActionMailer tests to fail when relying on the default settings. To resolve this inconsistency, you can explicitly set default_url_options[:host] to https://www.example.com|www.example.com in test.rb.
#RubyOnRails #ROR #ActionMailer #Capybara #TDD
Published
Author
user-image
Mohammad
SEO Best Practices:
• Meta titles should be between 50–60 characters long (including spaces).
• Meta descriptions should be between 120–160 characters (including spaces).
• Use a single H1 tag per page, followed by a clear and consistent hierarchy of H2 and H3 tags across all pages.
• All images should have meaningful alt tags for accessibility and SEO.
• Ensure there are no broken links; tools like Screaming Frog can help detect them.
• Include canonical tags to avoid duplicate content issues.
• Add social meta tags (Open Graph, Twitter Cards) for better link previews.
• The site should have a robots.txt file and a sitemap.xml for better crawling and indexing.
#SEOBestPractices #SearchEngineOptimization
Published
Author
user-image
Syed
In Rails, default_scope is a way to automatically apply a query condition to every query for a model.
When we define a default_scope, it always gets added unless we manually remove it.

Example:

Ruby

default_scope { order(created_at: :asc) }


This ensures a consistent ordering across the app without needing to manually add .order(created_at: :asc) every time.
It's especially useful when displaying comments, messages, tasks, or anything that should appear in the order they were created.

Caution:
default_scope can sometimes be annoying if we want a different order temporarily.
In that case, we would need to call .unscope(:order) to remove it manually.

#rubyonrails
Published
Author
user-image
Nived
Instead of manually checking if a key exists in a hash, you can just say:


Ruby

counts = Hash.new(0)


Now whenever you do:


Ruby

counts[:apple] += 1


Ruby will assume counts[:apple] starts at 0, so no errors — just clean, readable code.

#ruby
Published
Author
user-image
Syed
Traits are reusable groups of attributes that we can apply to factories conditionally.
They help avoid duplication and let us customise factories based on different test scenarios.


We can define a trait inside a factory block using the trait keyword


Code

FactoryBot.define do
  factory :user do
    name { "John Doe" }

    trait :admin do
      role { "admin" }
    end

    trait :with_profile_picture do
      after(:build) do |user|
        user.profile_picture.attach(
          io: File.open(Rails.root.join('spec/fixtures/files/test.jpg')),
          filename: 'test.jpg',
          content_type: 'image/jpeg'
        )
      end
    end
  end
end


And then we can use them in our specs. And traits can override any attribute defined in the factory


Code

create(:user, :with_profile_picture)
create(:user, :admin, :with_profile_picture)


#CU6U0R822 #rspec
Published
Author
user-image
Syed
define_singleton_method dynamically adds a method to a single object instance without modifying the class itself. This is useful when you need custom behaviour for an individual object at runtime.

It only modifies the behaviour of a single object in memory at runtime. It does not persist any changes to the database or schema.


Ruby

user = User.new(name: "Sibtain")

user.define_singleton_method(:greet) do
  "Hello, my name is #{name}!"
end

puts user.greet # => "Hello, my name is Sibtain"


#CU6U0R822
Published
Author
user-image
Nived
PostgreSQL's jsonb type stores structured JSON data efficiently. Unlike json, it's binary-optimized, supports indexing, and queries faster.
🔹 Why Use jsonb?
• Stores structured data in a single column.
• Faster queries (no reparsing needed).
• Supports indexing for quick lookups.
• Flexible schema—great for dynamic data.
• Allows key-value updates without rewriting the whole object.
• Removes duplicate keys automatically.
jsonb gives you NoSQL flexibility with SQL power! 🚀

#postgres
Published
Author
user-image
Puneeth
Aliasing in Ruby
Aliasing in Ruby helps to eliminate code repetition by providing an alternative name for an existing method, allowing it to be called in different ways without duplicating the logic.
For example,

Ruby

module QuestionsHelper
  def can_modify_question?(question)
    !question.survey.has_answers?
  end

  alias_method :can_edit_question?, :can_modify_question?
  alias_method :can_delete_question?, :can_modify_question?
end


#ruby #aliasing
Published
Author
user-image
Nived
Turbo provides a built-in way to show a loading state on form submission using the turbo_submits_with attribute! 🚀
Instead of manually handling the button's disabled state or adding a spinner, you can simply use:


Code

<%= form.submit t("post.create"), 
  data: { turbo_submits_with: t('loading.saving') } %>


• When the form is submitted, Turbo automatically
replaces the button text with the value provided in turbo_submits_with (e.g., "Saving...").

• Button is also disabled until the request completes.
• Once the request completes, the button reverts to its original text.
No extra JavaScript needed! 🎉

This is a great way to enhance UX with minimal effort. #Rails #Turbo #TIL
Published
Author
user-image
Satya
while using form.number_field in rails if we enter a floating point value eg: 23.45 then browser default validation kicks in syaing: Please enter a valid value. The two nearest valid values are 23 & 24 .
In order to allow the floating point value we can add form.number_field, step: "0.01" . Then we can add upto two decimal point vlaue.

#CU6U0R822 #form-tag-helper
Published
Author
user-image
Satya
to terminate google chrome sessions -> pkill -9 "Google Chrome" .
#terminate-session
Published
Author
user-image
Satya
Ruby Heredoc Syntax & Rails .squish method:
• Bad - Regular heredoc (<<) keeps all whitespace

Code

query = <<SQL
    SELECT *
    FROM users
SQL
# Result: "    SELECT *\
    FROM users\
"


• Good - Squiggly heredoc (<<) removes leading whitespace

```
query = <<
SQL
SELECT *
FROM users
SQL
# Result: "SELECT \
FROM users\
"
```

• *
Best - Rails .squish removes all extra whitespace/newlines

Code

query = <<~SQL.squish
    SELECT *
    FROM   users
    WHERE  active = true
SQL
# Result: "SELECT * FROM users WHERE active = true"


#ruby-heredoc #rails-squish
Published
Author
user-image
Puneeth
TimescaleDB

When working with time series data like stock prices, website traffic, or error logs, the volume of data grows rapidly over time. In traditional relational databases like PostgreSQL and SQL, this can lead to slower query performance as the dataset becomes larger.

One alternative is to use NoSQL databases, but they come with their own challenges, such as lack of strong ACID compliance, complex querying, and difficulties in handling structured relational data.

TimescaleDB, which is built on top of PostgreSQL, offers a powerful solution by introducing hypertables - a special type of table optimised for time series data. Hypertables enable faster read and write operations, automatic partitioning, and efficient data compression. Additionally, TimescaleDB provides advanced analytical functions, making it easier to perform complex queries for reporting, trend analysis, and forecasting. This makes it a great choice for applications that require efficient storage and analysis of large-scale time series data.

#databases #time_series_data #timescale_db #postgres
Published
Author
user-image
Codemancers
We can't use turbo frame for table rows, because html doesn't allow external tag like turbo frame inside the table.

The workaround this is to just have unique id for element you want to modify and use turbosteam to modify only that element.

#rubyonrails #turbo #turboframes #spa
Published
Author
user-image
Satya
in ruby https://nil.to|nil.to_i => 0 & https://nil.to|nil.to_f => 0.0
#ruby, #nil-conversion
Published
Author
user-image
Sujay
Steps to merge one repo into another

Step 1: Clone Repo1 locally

Code

git clone <repo1-url> repo1
cd repo1


Step 2: Fetch all the branches and commits from Repo2

Code

git remote add repo2 <repo2-url>
git fetch repo2


Step 3: Create a branch

Code

git checkout -b merge-repo2


Step 4: Merge keeping full history

Code

git merge --allow-unrelated-histories repo2/main (Since the repositories have separate histories, this option allows Git to combine them, potentially requiring manual conflict resolution)


Step 5: Resolve Merge Conflicts

Code

git add .
git commit -m "Resolved merge conflicts"


#git
Published
Author
user-image
Mohammad
pagy_array This method is the same as the generic pagy method, but specialized for an Array.

Ruby

require 'pagy/extras/array'
@pagy, @items = pagy_array(an_array)


#CU6U0R822 #ruby
Published
Author
user-image
Mohammad

```
pagy_array
Published
Author
user-image
Nived
each_with_object is an enumerable method in Ruby that allows you to iterate over a collection while building up an object (like an array or hash). Unlike map, which creates a new array, each_with_object lets you modify an existing object in a single pass.

Syntax

Ruby

collection.each_with_object(initial_object) do |item, object|
  # Modify the object inside the block
end


collection: The array or enumerable you're iterating over.
initial_object: The object that will be modified (e.g., {} for a hash or [] for an array).
item: The current element in the iteration.
object: The object that accumulates the results.
Example Usage
Using each_with_object with a Hash

Ruby

numbers = [1, 2, 3, 4, 5]
squares = numbers.each_with_object({}) do |num, hash|
  hash[num] = num**2
end

puts squares
# Output: {1=>1, 2=>4, 3=>9, 4=>16, 5=>25}


Why use each_with_object?
• Avoids the need to initialize an empty {} before the loop.
• Eliminates the need to return the object explicitly.

#CU6U0R822 #ruby

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