Saeloun Blog

https://blog.saeloun.com/

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

フィード

記事のアイキャッチ画像
Rails 7.1 Allows Validators To Accept Lambdas Without Record Argument
Saeloun Blog
Rails validations are a key feature for ensuring the integrity of the data being saved to the database. They allow us to define rules for model attributes, such as requiring a value, ensuring uniqueness, or excluding specific values. Rails also allows us to use custom logic for validations by using blocks or callable objects like lambdas.What Is a Lambda in Ruby?A lambda is a type of Proc object in Ruby with stricter rules.Argument checking: A lambda ensures the number of arguments passed matches the number expected. If not, it raises an error.Return behavior: A lambda returns control back to where it was called, instead of exiting the enclosing method like a regular proc.print_value = ->(x) { "Value: #{x}" }print_value.call(10) # Works fineprint_value.call(10, 20) # Raises an ArgumentErrorBefore Rails 7.1In earlier versions of Rails, lambdas used in validations required an argument, even if the argument was not needed. Without this, Rails would raise an ArgumentError.class User < Appl
1日前
記事のアイキャッチ画像
Rails 7.2 Prevents Job Scheduling Within Transactions.
はてなブックマークアイコン 1
Saeloun Blog
In Rails applications, it is common to perform actions that depend on the successful completion of database transactions. For instance, sending a notification after a record is updated or triggering a background job.BeforeWhen jobs are enqued within a transaction there’s a risk they might be executed before the transaction is fully committed.If the transaction is rolled back due to an error or other reasons, the job might still execute, even though the data it relies on was never committed to the database.This could lead to errors such as ActiveJob::DeserializationError or RecordNotFound.Consider a scenario where we confirm a user and want to send a notification afterwards:User.transaction do user.update(confirmed: true) UserNotificationJob.perform_later(user)endThis code might work in development but can fail in production due to timing issues with the database and job queue.If UserNotificationJob job runs before the transaction commits, it might fail because the user’s state hasn’t b
1日前
記事のアイキャッチ画像
Rails 7.1 Added Support For Array#intersect? To ActiveRecord::Relation.
Saeloun Blog
Ruby 3.1 introduced the Array#intersect? method which returns true if two arrays have at least one common element, otherwise returns false.fruits_list_1 = ['apple', 'banana', 'cherry']fruits_list_2 = ['orange', 'banana', 'grape']fruits_list_3 = ['kiwi', 'peach', 'mango']fruits_list_1.intersect?(fruits_list_2)=> truefruits_list_1.intersect?(fruits_list_3)=> falseBeforeTo check if two ActiveRecord relation objects have any common elements, we had to chain the intersection method with any? or empty? methods.products1 = Product.where(id: [1, 2, 3])=> [#<Product id: 1, name:...>, #<Product id: 2, name:...>, #<Product id: 3, name:...>]products2 = Product.where(id: [2, 4, 5])=> [#<Product id: 2, name:...>, #<Product id: 4, name:...>, #<Product id: 5, name:...>](products1 & products2).any?=> true(products1 & products2).empty?=> falseBut the ActiveRecord::Relation did not have built-in support for the Array#intersect method.products1.intersect?(products2)NoMethodError: undefined method `interse
5日前
記事のアイキャッチ画像
Rails 7.1 Adds --parent Option To The Controller Generator.
Saeloun Blog
Rails provides generators to quickly create files that follow Rails conventions.The most power-packed one is the scaffold generator which creates a model, controller, views, and tests for a given resource.Of course, each file can be created individually using the model, controller, and job generators.BeforeThe controller generator can be used to create an ApplicationController class, which serves as the base class for all controllers in the application.Prior to Rails 7.1, It was not possible to directly generate a controller that inherits from a class other than ApplicationController.We need to manually update the parent class in the controller file after it has been generated.rails generate controller project/paymentscreate app/controllers/project/payments_controller.rbinvoke erbcreate app/views/project/paymentsinvoke test_unitcreate test/controllers/project/payments_controller_test.rbinvoke helpercreate app/helpers/project/payments_helper.rbinvoke test_unit.....# app/controllers/proj
5日前
記事のアイキャッチ画像
Rails 7.1 Raises Error When Generating Model Attributes With Reserved Names.
はてなブックマークアイコン 1
Saeloun Blog
ActiveRecord migrations are a convenient way to modify our database schema over time.They allow us to create, modify, and manage database tables and columns, ensuring consistency across environments.BeforeCurrently, ActiveRecord::Migration has a weird behaviour where we can generate migrations with reserved keywords like attributes, type etc.bin/rails generate model Post title:text attributes:jsonbclass CreatePosts < ActiveRecord::Migration[6.0] def change create_table :posts do |t| t.text :title t.jsonb :attributes, default: '{}' t.timestamps end endendIt generates the migration without any issues. But it raises error when we try to use it.Post.create!(title: "Hello World", attributes: { category: 1 })=> attributes is defined by Active Record. Check to make sure that you don't have an attribute or method with the same name. (ActiveRecord::DangerousAttributeError)AfterThis problem is now fixed in Rails 7.1 with this PR#47752 where ActiveRecord::Migration raises error when generating mo
6日前
記事のアイキャッチ画像
Rails 7.1 Adds --unused Option To Detect Dormant Routes.
はてなブックマークアイコン 1
Saeloun Blog
As projects grow and undergo refactoring, some routes can become obsolete, leading to cluttered routing files and potential confusion. These unused or dormant routes are routes defined in the configuration but not actively used in the application.Dormant routes (extraneous routes)Dormant routes are defined routes that are not linked to any controllers, actions, or views. These unused routes can accumulate over time, making it difficult to manage and understand the routing configuration.BeforeIdentifying unused routes in a Rails application was previously a manual process. Since Rails did not provide built-in support for detecting dormant routes, developers had to rely on third-party gems (such as traceroute) or manually inspect routes, controllers, and views, which was both tedious and error-prone.Rails.application.routes.draw do get 'users/index' get 'users/show' get 'unused_route', to: 'users#unused'endIn this routing configuration, unused_route is defined but not actually used in th
7日前
記事のアイキャッチ画像
Understanding `inverse_of` In Rails Associations.
Saeloun Blog
ActiveRecord offers a range of powerful features, and one often overlooked yet highly useful option is inverse_of. This simple association option enables us to explicitly define bi-directional relationships between models.Bi-directional AssociationsIn Rails, bi-directional associations refer to relationships where two models reference each other, allowing data to flow in both directions. It makes easier to query, manipulate, and maintain data integrity.For instance, a Project has many Tasks, and each Task belongs to a Project. This allows us to traverse from a Project to its Tasks, and from a Task back to its Project.class Project < ApplicationRecord has_many :tasksendclass Task < ApplicationRecord belongs_to :projectendActiveRecord will try to automatically recognize the bi-directional association between two models based on the names of their associations.project = Project.firsttask = project.tasks.firstproject.name == task.project.name=> trueproject.name = "Changed Name"project.name
7日前
記事のアイキャッチ画像
Rails 7.1 Adds exclude? And extract_value methods To ActionController::Parameters
Saeloun Blog
Rails ActionController::Parameters is a convenient way to pass data from a request to a controller action.It allows us to choose which attributes should be permitted for mass updating and thus prevents accidentally exposing parameters that shouldn’t be exposed.Before exclude?To check if the given key is present in the parameters, we can use the include? method, but ActionController::Parameters does not provide any method to check if the given key is not present in the parameters.params = ActionController::Parameters.new(name: "John", age: 26)params.include?("name") #=> trueAfter exclude?Rails 7.1 adds exclude? method to ActionController::Parameters. It is the inverse of include? method.The exclude? method returns true if the given key is not present in the parameters.params.exclude?("name") #=> falseparams.exclude?("admin") #=> trueBefore extract_valueRails ActionController::Parameters did not provide a method for extracting parameter values for the given key separated by delimiter, so
13日前
記事のアイキャッチ画像
Rails 7.1 Supports Descending Order For in_batches Without Block
Saeloun Blog
ActiveRecord::Batches provides methods like find_each, find_in_batches, and in_batches to process records in batches, reducing the load on the database and memory consumption.By default, records are processed in ascending order by primary key(ID).Rails 6.1 has added support for providing order(ASC/DESC) to batch processing methods like find_each, find_in_batches and in_batches.BeforeBefore Rails 7.1, using in_batches without a block on an ActiveRecord relation did not support descending order, even if it was specified. Instead, records were processed in ascending order.Note that the ordering works fine for both find_each and find_in_batches methods with ASC/DESC.It also works fine when calling in_batches with a block.User.in_batches(order: :desc) {}(0.8ms) SELECT "users"."id" FROM "users" ORDER BY "users"."id" DESC LIMIT ? [["LIMIT", 1000]]But without a block it processes in ascending order.User.in_batches(order: :desc).each {}(0.4ms) SELECT "users"."id" FROM "users" ORDER BY "users"."
14日前
記事のアイキャッチ画像
Rails 7.1 Adds after_discard Method To ActiveJob For Discarded Jobs.
Saeloun Blog
ActiveJob is used to enqueue and run the tasks in the background.But a job can fail because of many reasons.BeforeTo manage job failures, ActiveJob provides methods like retry_on to reschedule job for re-execution and discard_on to discard the job with no attempts to retry , if the exception is raised.While these methods provide a way to handle errors and retries, ActiveJob does not provide any method to excute custom logic to handle job failures or to perform cleanup actions after a job is discarded.class MyJob < ApplicationJob discard_on StandardError def perform raise StandardError, "An error occurred" endendAfterRails 7.1 adds after_discard method to ActiveJob to run a callback when a job is about to be discarded.The after_discard callback allows us to define a block of code that runs after a job is discarded.This callback gives us access to both the job instance and the exception that caused the job to be discarded.after_discard do |job, exception| # add additional logic for error
25日前