Saeloun Blog

https://blog.saeloun.com/

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

フィード

記事のアイキャッチ画像
From Idea to Launch: Why Rails Remains the Ultimate MVP Framework in 2026
Saeloun Blog
IntroductionIn the fast paced world of startups, speed to market can make the difference between success and failure.Every day spent in development is a day without user feedback, without revenue, and without validation of the core business hypothesis.Ruby on Rails has been the secret weapon behind some of the world’s most successful startups includingAirbnb, Shopify, and Stripe.In this post, we’ll explore why Rails continues to be an excellent choice for MVP development, and how it can accelerate the journey from idea to launch.What Makes an Ideal MVP Framework?An ideal MVP framework should deliver speed without sacrificing quality.It needs sensible defaults so teams can focus on their unique value proposition rather than endless configuration decisions.A mature ecosystem of tools for common features like authentication and payments is essential.We shouldn’t reinvent the wheel.Finally, the framework should provide a clear path to scale as the product grows.Why Ruby on Rails Excels at
16時間前
記事のアイキャッチ画像
Rails 8.1 introduced except_on option for validations and callbacks
Saeloun Blog
Rails 8.1.0 introduces the except_on option for validations and validation callbacks, making it easier to skip them in specific contexts.In Rails, we can conditionally run validations. For example, we can run validations in certain contexts by using the on option.ValidationsBeforeThere was no direct way to exclude validations based on context (e.g., skipping validations during an update). We had to rely on custom conditional logic.The on: option had limited scope, allowing validations only during create or update.class Client < ApplicationRecord validates :name, presence: true, on: [:create]endClient.create!(name: "")`<main>': Validation failed: Name can't be blank (ActiveRecord::RecordInvalid)client.update!(name: "")Client Update (2.2ms) UPDATE "clients" SET "name" = ?, "updated_at" = ? WHERE "clients"."id" = ? [["name", ""], ["updated_at", "2025-12-17 14:49:27.360920"], ["id", 1]]=> true Using conditionals increased code complexity.class Client < ApplicationRecord validates :name, pr
10日前
記事のアイキャッチ画像
Mobile First Design | Why It Matters for Consultancies
Saeloun Blog
When we design websites for consultancies, one question always comes up: where do most people actually view the site? The answer is clear. Most visitors are on their phones. Whether it’s a potential client checking services between meetings or a business partner reviewing your work on the go, mobile is where that first impression happens. That’s why mobile first design has become essential, not optional.What Mobile First Design MeansMobile first design means creating a website for smaller screens before adapting it for larger ones. Instead of shrinking a desktop site down, we start by designing what users truly need on their phones. The goal is to make everything simple, readable, and fast to load.It’s not just about changing screen sizes. It’s about focusing on what matters most to the person visiting your site.Why It Matters for ConsultanciesFor consultancy firms, the website often creates the first impression. If it’s hard to use on mobile, visitors may leave before learning what yo
15日前
記事のアイキャッチ画像
Rails 8.1 introduces support for joins in update_all for Postgresql and SQLite.
Saeloun Blog
ActiveRecord joins is used to combine records from multiple tables based on associations,generating an SQL INNER JOIN.With update_all, we can update multiple records quickly without triggering model validations, callbacks, or modifying timestamps.Combining these two methods is useful when we need to perform bulk updates based on data from associated tables.For example, syncing a column value from a parent record to all its children in a single query.BeforeWhen we use update_all together with joins,Rails generates a subquery that prevents referencing joined tables in the SET clause,which results in an ActiveRecord::StatementInvalid error.For example:class Client < ApplicationRecord has_many :projectsendclass Project < ApplicationRecord belongs_to :clientendWith PostgresqlProject.joins(:client).update_all("name = clients.name")Project Update All (14.4ms) UPDATE "projects" SET name = clients.name WHERE "projects"."id" IN (SELECT "projects"."id" FROM "projects" INNER JOIN "clients" ON "cli
21日前
記事のアイキャッチ画像
Rails 7.1 allows passing validate(_check)_constraint through change_table
Saeloun Blog
When we are running Rails migrations,it’s common to combine multiple changes into a singlechange_table block especially when we want to keep database schema in sync.Before Rails 7.1Previously,validate_constraint andvalidate_check_constrainthad to be called outside the change_table block,requiring constraint creation andvalidation to be handled as two separate steps.For example:class AddNameColumnsAndConstraintToUser < ActiveRecord::Migration[7.0] def change change_table :user, bulk: true do |t| t.string :first_name t.string :last_name t.check_constraint "first_name IS NOT NULL AND last_name IS NOT NULL", name: "name_not_null", validate: false end validate_check_constraint :user, "name_not_null" endendAfterWith the enhancement introduced in Rails 7.1,we can now create cleaner migrations by combining column additions andconstraint validations within a single change_table block.def validate_constraint(*args) @base.validate_constraint(name, *args)enddef validate_check_constraint(*args) @ba
24日前
記事のアイキャッチ画像
Rails 8.1 now sorts table columns alphabetically when dumping the schema
Saeloun Blog
schema.rb documents the database structure in a database-agnostic way, providing a Ruby representation of the schema within the limits of what Active Record can express.BeforeWhen running migrations, Rails generates the schema.rb file by dumping the current database structure. However, the order of columns in schema.rb reflects the physical column order in the database, which typically follows migration history.Imagine you have a posts table:create_table "posts", force: :cascade do |t| t.string "title" t.boolean "published" t.text "summary"endAfter applying different migrations, the order of columns may differ on other machines:create_table "posts", force: :cascade do |t| t.string "title" t.text "summary" t.boolean "published"endThis can lead to merge conflicts when two branches modify the same table concurrently, creating confusion and clutter, particularly when several developers are working together.AfterStarting with Rails 8.1, table columns are sorted alphabetically when dumping t
25日前
記事のアイキャッチ画像
Upgrading from Rails 5.2 to Rails 6 - Modern Rails Features
Saeloun Blog
Rails 6 is a major milestone that modernizes Rails for the 2020s.The biggest change?Zeitwerk autoloader replaces the classic autoloader, requiring careful attention to file naming conventions.Plus: Webpacker as default, multiple database support, parallel testing, Action Mailbox, and Action Text.Note: This is Part 3 of our Rails Upgrade Series. Read Part 1: Planning and Part 2: Rails 4.2 to 5 first.Before We StartExpected Timeline: 2-4 weeks for medium sized applicationsMedium-sized application: 20,000-50,000 lines of code, 30-100 models, moderate test coverage, 2-5 developers. Smaller apps may take 1-2 weeks, larger enterprise apps 6-12 weeks.Prerequisites:Currently on Rails 5.2 (upgrade from 5.0/5.1 first)Ruby 2.5.0+ installed (Ruby 2.6 or 2.7 recommended)Test coverage of 80%+Understanding of app’s file structureRuby Version RequirementsRails 6 requires Ruby 2.5.0 minimum, but we strongly recommend Ruby 2.6 or 2.7 for production.Ruby Version FeaturesRuby 2.5 (December 2017):yield_sel
1ヶ月前
記事のアイキャッチ画像
What Is New In Ruby 4.0
Saeloun Blog
Ruby 4.0 is here, releasing on Christmas Day 2025, marking 30 years since Ruby’s first public release.This release packs some genuinely exciting features.Let’s explore the most impactful changes in Ruby 4.0.ZJIT - A New JIT CompilerRuby 4.0 introduces ZJIT, a new just in time compiler built by the same team behind YJIT.Unlike YJIT’s lazy basic block versioning approach, ZJIT uses a more traditional method based compilation strategy.The key difference?ZJIT is designed to be more accessible to contributors.It follows a “textbook” compiler architecture that’s easier to understandand modify.To enable ZJIT, we can use the --zjit flag:ruby --zjit my_script.rbWhile ZJIT is faster than interpreted code, YJIT remains the recommended choice for production.ZJIT sets the foundation for future performance improvementsand community contributions.Ruby::Box - Isolated NamespacesRuby::Box is an experimental feature that brings isolated namespaces to Ruby.This allows us to load multiple versions of a li
1ヶ月前
記事のアイキャッチ画像
Upgrading from Rails 4.2 to Rails 5 - A Complete Guide
Saeloun Blog
Rails 5 brought major improvements: ActionCable for WebSockets, API mode, Turbolinks 5, and ActiveJob integration.But it also introduced breaking changes that require careful migration.If we’re still on Rails 4.2 (EOL since 2016), this upgrade is critical for security and performance.Let’s walk through the key changes and how to handle them.Note: This is Part 2 of our Rails Upgrade Series. Read Part 1: Planning Rails Upgrade for strategic planning guidance.Before We StartExpected Timeline: 2-4 weeks for medium-sized applicationsMedium-sized application: 20,000-50,000 lines of code, 30-100 models, moderate test coverage, 2-5 developers. Smaller apps may take 1-2 weeks, larger enterprise apps 6-12 weeks.Prerequisites:Test coverage of 80%+Ruby 2.2.2+ installed (Ruby 2.3+ recommended)Backup of production databaseStaging environment for testingRuby Version RequirementsRails 5 requires Ruby 2.2.2 minimum, but we strongly recommend Ruby 2.3 or 2.4 for production.Why Upgrade Ruby First?Ruby 2.
1ヶ月前
記事のアイキャッチ画像
Rails 8.1 Introduces Structured Event Reporting with Rails.event
Saeloun Blog
IntroductionModern observability platforms thrive on structured data.They can parse JSON, extract fields, build dashboards,and alert on specific conditions.But Rails has traditionally given us Rails.logger,which produces human readable but unstructured log lines.Parsing these logs for analytics is painful.We end up writing regex patterns,hoping the log format doesn’t change,and losing valuable context along the way.Rails 8.1 introduces a first class solution:the Structured Event Reporter,accessible via Rails.event.BeforeBefore this change,logging in Rails meant working with unstructured text.Rails.logger.info("User created: id=#{user.id}, name=#{user.name}")This produces a log line like:User created: id=123, name=John DoeTo extract meaningful data from this,observability tools need to parse the string.If we change the format slightly,our parsing breaks.We also lack consistent metadata.Where did this log come from?What request triggered it?What was the timestamp with nanosecond precisio
1ヶ月前