Saeloun Blog

https://blog.saeloun.com/

Ruby on Rails and ReactJS consulting company. We also build mobile applications using React Native

フィード

記事のアイキャッチ画像
Customizing Rails Migrations with Execution Strategies
Saeloun Blog
IntroductionRails migrations are powerful tools for managing database schema changes.However, there are scenarios where we need more control over how these migrations execute.We might need to log every schema change for audit purposes.We might want to prevent dangerous operations in production environments.Or we might need to route migrations through an external service for distributed systems.Rails 7.1 introduced Execution Strategies to address these needs.This feature provides a way to customize the entire migration execution layer.It has been available since Rails 7.1 and continues to work in Rails 8.x.This post explores how Execution Strategies work and demonstrates practical use cases.Before Rails 7.1Before Rails 7.1, migrations had limited customization options.A typical Rails migration looked like this:class CreateUsers < ActiveRecord::Migration[7.0] def change create_table :users do |t| t.string :name t.timestamps end endendWhen we called create_table, Rails used method_missing
4日前
記事のアイキャッチ画像
Rails 8 adds conditional allow_nil and allow_blank in model validations
Saeloun Blog
We often need validations that adapt dynamically to the state of a model. At the same time, we want to avoid duplication and keep our code DRY. Rails 8.1 introduced the ability to pass a callable to allow_nil and allow_blank, giving us exactly that: validations that are conditional and easy to maintain.In this post, we’ll explore this feature through a book publishing workflow. Imagine a Book model with attributes like isbn and status. Draft books are treated differently from published ones, and we want a validation setup that is clear, concise, and maintained in a single place.BeforeIn older Rails versions, allow_blank could not be conditional. We duplicated validations to express different behavior. We ended up repeating the same format rule.class Book < ApplicationRecord # attribute :isbn, :string enum :status, { draft: 0, submitted: 1, published: 2 } validates :isbn, format: { with: /\A\d{13}\z/, message: "must be a 13-digit number" }, unless: :draft? validates :isbn, format: { wit
5日前
記事のアイキャッチ画像
Lexxy - The next generation rich text editor for Rails
Saeloun Blog
What is Lexxy?Lexxyis a new rich text editor for Action Text, developed by Basecamp. It is built on top ofLexical.Lexical is a fast, robust, flexible framework for building text editors, developed by Meta (and used in WhatsApp and Facebook apps).Lexxy makes it easy to write and format rich text content. It is designed to work smoothly with Action Text and Active Storage, so users can add images, videos, and other files directly in the editor.Motivation for LexxyLexxy was created because Trix didn’t meet Basecamp’s expectations or support all the features they wanted to offer. With Lexxy, the team now has a strong foundation to build on.Let’s see which features Lexxy offers as compared to Trix.Trix vs LexxyFeature Trix Lexxy Paragraph markup Uses <div> & <br> tags Uses real <p> tags for paragraphs Markdown support None Full support with shortcuts and auto-formatting Code syntax highlighting Very limited Real-time highlighting with language select Paste links on selected text No Yes, lin
1ヶ月前
記事のアイキャッチ画像
Rails Decouples Trix From Action Text Into action_text-trix gem
Saeloun Blog
Action Text is a power-packed tool designed to build WYSIWYG editors for our Rails applications easily.Action Text brings rich text content and editing to Rails.TrixTrix is developed by Basecamp.According to its official website:Trix is an editor for writing messages,comments,articles,andlists—the simple documents most web apps are made of.It features a sophisticated document model,support for embedded attachments,andoutputs terseand consistent HTML.We can read more about Trix,all the features it offers,andwhat are its advantages over most other WYSIWYG editorsoverhere.BeforeHistorically, Trix was bundled directly with Action Text in Rails, meaning that updating Trix often depended on a new Rails release.This tight coupling could slow down the adoption of new Trix features or, more critically, security fixes.Another common approach involved using the Trix npm package. If we used bin/importmap pin to manage Trix in our Rails application, the npm package would be downloaded and vendored
2ヶ月前
記事のアイキャッチ画像
Rails 8 does not include redis by default in the dev container.
Saeloun Blog
A development container (or dev container for short) allows us to use a container as a full-featured development environment.It can be used to run an application, to separate tools, libraries, or runtimes needed for working with a codebase, and to aid in continuous integration and testing.The dev containers can be run locally or remotely, in a private or public cloud, in a variety of supporting tools and editors.BeforeRails 7.2 ships with dev containers as an opt-in feature.Adding dev container on a new rails apprails new <app_name> --devcontainerAdding dev container to an existing rails appbin/rails devcontainerThe .devcontainer folder includes everything needed to boot the app and do development in a remote container.The container setup includes:A redis container for Kredis, ActionCable etc.A database (SQLite, Postgres, MySQL or MariaDB)A Headless chrome container for system testsActive Storage configured to use the local disk and with preview features workingHere is the default .dev
4ヶ月前
記事のアイキャッチ画像
Rails now allows associations to be marked as deprecated using deprecated: true
Saeloun Blog
Active Record allows developers to mark associations as deprecated, providing robust reporting mechanisms to identify and eliminate their usage across all environments.It supports multiple reporting modes and configurable backtraces, making the process of cleaning up or removing associations much safer and more efficient.BeforeWe had no built-in way to deprecate associations. Removing an association like this:has_many :projectsmeant deleting projects and hoping CI or manual testing would catch all usage. This is risky in production, especially with incomplete test coverage or mocked associations.AfterRails introduces deprecated: true for the deprecated associations. With this, Active Record warns every time the association is used.We can easily mark an association as deprecated by adding the :deprecated option to our has_many, belongs_to, or other association declarations before deleting them.class Client < ApplicationRecord has_many :projects, deprecated: trueendWith this, Active Reco
4ヶ月前
記事のアイキャッチ画像
New features in ECMAScript 2025
Saeloun Blog
In June 2025, the 129th General Assembly approved the ECMAScript 2025 language specification, which means that ECMAScript 2025 is officially a standard now.In this blog, we will explore the new features in detail.Iterator helpersMDN defines iterators asIterators are objects which implement the Iterator protocolby having a next() method that returns an object with two properties:value: The next value in the iteration sequence.done: This is true if the last value in the sequence has already been consumed. If value is present alongside done, it is the iterator’s return value.Before the standardization of iterator helper methods in ECMAScript 2025, JavaScript lacked built-in methods like .map(), .filter(), .reduce(), etc., directly on iterator objects. This made working with iterators less convenient as compared to arrays. Developers had to use alternative approaches to achieve similar functionality:Converting iterators to arrays, losing the lazy and potentially infinite behavior of iterat
4ヶ月前
記事のアイキャッチ画像
Rails uses self-join for UPDATE with outer joins on PostgreSQL and SQLite
Saeloun Blog
ActiveRecord joins is used to combine records from multiple tables based on associations. In this blog, we will discuss how UPDATE statements with outer joins are handled in PostgreSQL and SQLite.class Client < ApplicationRecord has_many :projectsendclass Project < ApplicationRecord belongs_to :clientendBeforeWhen we do UPDATE with an OUTER JOIN and reference the updated table in the ON clause in PostgreSQL and SQLite, Rails generated subqueries as the join condition cannot be safely moved to the WHERE clause without breaking the query.Client.joins("LEFT JOIN projects ON projects.client_id = clients.id") .where("projects.id IS NULL") .update_all(name: 'Archived Client')UPDATE "clients" SET "name" = 'Archived Client' WHERE ("clients"."id") IN ( SELECT "clients"."id" FROM "clients" LEFT JOIN projects ON projects.client_id = clients.id WHERE (projects.id IS NULL))This approach was less efficient, especially for large datasets, and generated more complex SQL. The subquery added unnecessary
5ヶ月前
記事のアイキャッチ画像
Rails 8 adds built in authentication generator
Saeloun Blog
For developers to setup the basic authentication flow in Rails application, we have to do lot of manual configurations.New developers and small projects teams don’t even need major authentication related feature. But they still need to rely on third party gems or write the whole codebase of the authentication flow from scratch, which is time consuming.Rails has built in generators(eg: model, migration) for different features to avoid manaul coding and configurations. These generators allow developers to focus on building the core features of their application, rather than spending time on basic setup tasks.Authentication generatorRails 8 introduced the basic authentication generator which will add the required codebase for the basic auth flow setup in a Rails application.To add basic authentication to the app, we can use the following authentication generator command:bin/rails generate authenticationIt generates the following files with the necessary configurations. Here is the gist of
6ヶ月前
記事のアイキャッチ画像
Rails stops generating bundler binstub(bin/bundle)
Saeloun Blog
Bin folderIn a Rails application, the bin/ folder contains executable scripts that help manage the application. These scripts are generated when we create a new Rails project and ensure that commands like rails, rake, and bundle use the correct environment and gem versions defined in the Gemfile.lock.Example:bin/rails – Runs Rails commands.bin/rake – Runs Rake tasks.bin/setup – Prepares the app for development.Basically, Rails encourages us to use bin/rails rather than just rails because that loads the rails executable from within the bin/ subfolder of our app, ensuring we get the correct version. If we run rails all by itself, that could run any rails executable anywhere on our hard drive.Run bin/rails s instead of rails s to run the server.bin/bundle ensures that the correct version of Bundler is used in our Rails application when running commands like bin/rails s.BeforePreviously, when we created a new Rails app using:rails new myappIt generated a bin/bundle file that activated the
7ヶ月前