Saeloun Blog

https://blog.saeloun.com/

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

フィード

記事のアイキャッチ画像
React 19 Ref Updates - Prop Support & Cleanup Function!
Saeloun Blog
React 19 makes ref easier – just pass it!React 19 brings many exciting updates, and one of the simplest yet powerful change is how ref works. We no longer need forwardRef when passing ref to built-in elements like inputs. Cool, right?This small update makes working with ref much simpler, especially in forms where smooth user interactions matter.The problem with forwardRefBefore React 19, if a parent component wanted to interact with a child component using a ref, we had to wrap the child in forwardRef. Annoying, right?It made the code harder to read and maintain, especially in large projects.Thankfully, React 19 makes ref handling much easier.Let’s check out why ref became smarter than before with an example!Understanding the change with a pizza exampleImagine we have a Pizza Order form with reusable components for selecting pizza type and size. Now, what if selecting a pizza automatically moves the cursor to the size selection field? That would make ordering even smoother, right?Befor
4日前
記事のアイキャッチ画像
Rails 8 Removes Channels From Default App Structure.
Saeloun Blog
ActionCable integrates websockets with our app which allows two-way communication between the server and client without the need for continuous page refreshes, making real-time updates possible.Channels are similar to controllers in that we define methods for broadcasting or streaming data to connected clients.BeforeBy default, Rails would create a channels folder in the app/ directory to store these channel definitions, allowing developers to easily set up real-time features.# Before Rails 8 when we generate rails new app# Rails app folder structure/app /assets /channels /controllers /helpers /javascript /jobs /mailers /models /viewsAfterRails 8 now removes channels from default app/ structure when we generate new app with rails new command.Now that Hotwire is the default in Rails, this change drops the channels folder from default app/ structure.# Rails app folder structure looks like/app /assets /controllers /helpers /javascript /jobs /mailers /models /viewsThe folder still gets cre
4日前
記事のアイキャッチ画像
Rails Introduces ActiveModel::Attributes::Normalization
Saeloun Blog
When we work with user input, we want to sanitaize the data shared by user. Sometimes we want to format the data before saving it to the database(eg: downcase emails).Normalization allows us to keep the data clean, consistent and predictable. We can format the data before saving it to the database or further processing.For example, imagine a user signing up with [email protected] and another with [email protected]. Without downcasing these emails, even though they’re the same but system treats them as different emails. We can normalize the email format before saving it to the database.BeforeRails 7.1 introduced ActiveRecord::Base::Normalization, we can specify unique normalization rules for model attributes. When an attribute is assigned or changed, normalization is applied, and the normalised value is stored in the database.The normalizes(*names, with:, apply_to_nil: false) method takes name of the attribute and a block that defines the normalization logic.options:with -> Any callable
18日前
記事のアイキャッチ画像
Bulk Migrations by 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 thevalidate_constraint andvalidate_check_constraint was called outside of thechange_table block to check constraint and its validations into two distinct stepsFor 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" endendAfterRails 7.1 addedthe enhancement,we can now write cleaner migrations by combining column additionsand constraint validations within a single change_table block.def validate_constraint(*args) @base.validate_constraint(name, *args)enddef validate_check_constraint(*args) @base.validate_check_constraint(nam
22日前
記事のアイキャッチ画像
Deep Dive Into Rails ActionController Strong Parameters
Saeloun Blog
ParametersThe data sent with incoming request is known as parameters. The parameters in Rails can be found in the params hash and include:Path Parameters: Embedded in the URL, e.g., /posts/:id.Query String Parameters: Added to the URL, e.g., /posts?title=rails.Form Data: Submitted via forms using POST requests.JSON Data: In APIs where the request body contains JSON.Unlike a plain Ruby hash, the params hash is an ActionController::Parameters object which treats symbols (e.g., :key) and strings (e.g., "key") as equivalent keys.Strong ParametersStrong parameters allow us to explicitly permit and require specific attributes in the controller, preventing mass assignment vulnerabilities.We can manually filter parameters:class PostsController < ApplicationController def create @post = Post.create( title: params[:title], content: params[:content] ) endendTestcase: params = { title: "Welcome to Rails", content: "Deep dive into rails...", published: true }Output: { title: "Welcome to Rails", con
1ヶ月前
記事のアイキャッチ画像
Rails 8 Adds A New Script Folder By Default And Scripts Generator.
Saeloun Blog
In Rails there is no official way to organize one-off scripts. Unlike recurring tasks, which are automated or scheduled to run at regular intervals (e.g., cron jobs or background workers), these scripts are standalone, ad-hoc scripts that are intended to be run only once or on rare occasions.BeforeBefore Rails 8, managing one-off or custom scripts was often chaotic because there was no dedicated folder for scripts that didn’t fit standard Rake tasks or background jobs. This lack of organization made it harder to keep track of these scripts.As a result, we had to create our own ad-hoc methods for storing and running these scripts. This lead to inconsistent and cluttered solutions.Sometime developers use the bin/ folder but it is primarily for system-level scripts and placing project-specific scripts here often led to confusion.Developers would create custom folders like scripts/, utils/, or tasks/ to store these custom files. While this worked, it caused inconsistency across different R
2ヶ月前
記事のアイキャッチ画像
Rails 8 Now Uses ISO 8601 Style Time For TimeWithZone#inspect.
Saeloun Blog
The TimeWithZone is a Time-like class that can represent a time in any time zone. It is necessary because standard Ruby Time instances are limited to UTC and the system’s ENV['TZ'] zone.TimeWithZone instances implement the same API as Ruby Time instances, so that Time and TimeWithZone instances are interchangeable.TimeWithZone#inspect Returns a string of the object’s date, time, zone, and offset from UTC.BeforeTimeWithZone#inspect used an RFC822-inspired format for displaying timestamps. For instance:Time.zone.now.inspect#=> "Mon, 30 Sep 2024 05:04:48.516544000 UTC +00:00"This format is readable but lacks consistency with Ruby’s internal Time#inspect, which follows the ISO 8601 standard.AfterRails 8 now uses ISO 8601 style time for TimeWithZone#inspect method like Time#inspectTime.zone.now.inspect#=> 2024-09-30 10:37:27.675403 +0530 The update to TimeWithZone#inspect aligns Rails with Ruby standards, ensuring time formatting consistency across the board.
2ヶ月前
記事のアイキャッチ画像
What Is New In Ruby 3.4
Saeloun Blog
It’s official, Ruby 3.4 first release is available, bringing a wave of excitement to the Ruby community.In this blog, we will go through the latest features, enhancements, and bugfixes introduced in the Ruby 3.4Prism is the new default parserRuby 3.4 switches the default parser from parse.y to Prism, which was introduced in Ruby 3.3 as a new parser designed for better maintainability, error tolerance, and performance.To use the conventional parser, use the command-line argument --parser=parse.y. Feature #20564.Garbage CollectionRuby 3.4 introduced several notable features and enhancements related to its garbage collection (GC) system, aimed at improving performance and flexibility. Here are the key updatesRuby 3.4 allows us to dynamically load different GC implementations. Enable it by configuring Ruby with --with-modular-gc at build time and load GC libraries at runtime with the RUBY_GC_LIBRARY environment variable. Feature #20351.The default GC is now separated into its own library,
3ヶ月前
記事のアイキャッチ画像
Rails 8 Adds if_not_exists Option On The add_enum_value.
Saeloun Blog
Rails 7 added support for custom enum types in PostgreSQL with introduction of create_enum to add a new enum type and t.enum to add a column.Rails 7.1 has extended the ability to rename an enum, add enum value and rename enum value for the Postgres database adapter.The add_enum_value method provides a straightforward way to add new values to a PostgreSQL enum type without needing to execute raw SQL.class AddEnumToArticles < ActiveRecord::Migration[7.2] def change create_enum :status, ["draft", "published", "archived", "trashed"] safety_assured do change_table :articles do |t| t.enum :current_status, enum_type: "status", default: "draft", null: false end end endendclass AddReviewToArticleStatus < ActiveRecord::Migration[7.2] def change add_enum_value :status, 'review' endendBeforeWhen we use add_enum_value, PostgreSQL checks for duplicates and raises a PG::DuplicateObject error if a value already exists. ActiveRecord captures this as ActiveRecord::StatementInvalid when trying to add a d
3ヶ月前
記事のアイキャッチ画像
Filter and Require Params in Rails 8 with Parameters#expect
Saeloun Blog
Rails 8 introduces params#expect, a new method that enhances parameter handling by filtering parameters based on expected types. This reduces errors caused by tampering or invalid input.BeforeActionController parameters allows us to choose which attributes should be permitted with the help of require and permit. By default, the recommended way of handling parameters in Rails works fine. Until someone using our app starts messing with the parameters and causing 500 errors.params.require(:post).permit(:title, :summary, categories: [:name])http://localhost:3000/?post[title]=Hello World#=> {"title"=>"Hello World"}Passing a String Instead of a HashIf someone tampered params by passing string instead of hash. This throws NoMethodError because the permit is called on string.http://localhost:3000/?post=Hello World#=> {"post"=>"Hello World"}Completed 500 Internal Server Error in 28ms (ActiveRecord: 0.0ms (0 queries, 0 cached) | GC: 23.3ms)NoMethodError undefined method `permit' for "Hello World
4ヶ月前