Saeloun Blog
https://blog.saeloun.com/
Ruby on Rails and ReactJS consulting company. We also build mobile applications using React Native
フィード

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.
1

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
9日前

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.
1ヶ月前

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,
2ヶ月前

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
2ヶ月前

Rails 8 Adds Parameters#expect To Safely Filter And Require Params.
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
2ヶ月前

Rails 8 Allows drop_table To Accept An Array Of Table Names.
Saeloun Blog
ActiveRecord provides drop_table method to drop a table from database using migration.class DropPosts < ActiveRecord::Migration[7.2] def change drop_table :posts endendBeforeIf we want to drop multiple tables in one call using drop_table, ActiveRecord did not provide direct support.So we have to either call drop_table multiple times or use raw SQL.class DropMultipleTables < ActiveRecord::Migration[7.2] def change drop_table :users drop_table :posts drop_table :comments endclass DropMultipleTables < ActiveRecord::Migration[7.2] def change [:users, :posts, :comments].each do |table_name| drop_table table_name end endendActiveRecord::Base.connection.execute 'DROP TABLE users, posts, comments'AfterRails 8 adds support to drop multiple tables in one call using drop_table on ActiveRecord.drop_table :table1, :table2, :table3With this update, Rails allows drop_table to accept an array of table names.class DropMultipleTables < ActiveRecord::Migration[8.0] def change drop_table :users, :posts, :
3ヶ月前

Implementing Passwordless Authentication with WebAuthn in Rails
Saeloun Blog
What is Passwordless authentication?Passwordless authentication is an authentication method that verifies users identity and grant access to a site or system without using password. Instead, users can authenticate using methods like:Biometrics: Face ID, Touch IDHardware tokens: Devices like YubiKeysDigital tokens: Generated by authenticator appsMagic links: Sent to the user’s emailThis method enhances security and simplifies the login process by eliminating password vulnerabilities.What is WebAuthn?WebAuthn (Web Authentication API) is a W3C and FIDO standard that provides strong, passwordless authentication using public-key cryptography. It replaces passwords and SMS-based methods with secure, user-friendly solutions.How Does WebAuthn Work?1) Public Key Generation (Registration): During registration, the authenticator generates a public-private key pair. The public key is sent to the server and stored, while the private key stays securely on the authenticator.2) Private Key Usage (Auth
3ヶ月前

Rails 8 Adds Ability To Use Multiple Rate Limits Per Controller.
Saeloun Blog
Rate limiting is a crucial technique for managing server traffic, enhancing performance, and bolstering security. By controlling the number of incoming requests over a specific time, it protects systems from abuse and overload.BeforeIn Rails 7.2, rate limiting was introduced to Action Controller, enabling developers to limit requests to specific actions within a defined time period.class PostsController < ApplicationController rate_limit to: 10, within: 3.minutes, only: :createendHowever, the limitation here was the inability to define multiple rate limits for different use cases within the same controller.AfterRails 8 introduces support for multiple rate limits per controller. This enhancement allows developers to apply distinct rate limits to the same action or across multiple actions by using the name: option.class PostsController < ApplicationController rate_limit to: 3, within: 2.seconds, name: "short-term", only: :create # Long-term limit for general access rate_limit to: 10, wit
3ヶ月前

Rails 7.2 Added Support For Explain Method To ActiveRecord::Relation.
Saeloun Blog
When optimizing database queries in Rails, it’s essential to understand how the database plans to execute a query. Rails provides a built-in method, ActiveRecord::Relation#explain, to analyze and display a query’s execution plan. The output mimics the format of a database shell, offering valuable insights into query performance and potential bottlenecks.BackgroundBefore Rails 7.1, the explain method provided basic query execution plans. Rails 7.1 introduced options like analyze and verbose to offer deeper insights into query performance. You can learn more about this in our blog post.With Rails 7.2, the feature has been further enhanced. The explain method now supports pluck, count, first, and other methods directly on an ActiveRecord::Relation, making it even more powerful and user-friendly.What Is ActiveRecord::Relation#explain?The explain method runs the database’s EXPLAIN command on the query triggered by the relation and returns the result. This allows us to:See how the database w
3ヶ月前