Ruby and Ruby on Rails: Tips and Tricks #4

Erim Icel
10 min readMay 12, 2023

Welcome back to the fourth part of Ruby and Ruby on Rails: Tips and Tricks, where we’ll continue exploring some essential tips for working with Ruby on Rails. I hope you find these tips and tricks helpful in your day-to-day work. So, let’s dive in!

Ruby and Ruby on Rails: Tips and Tricks Series

Ruby and Ruby on Rails: Tips and Tricks #1
Ruby and Ruby on Rails: Tips and Tricks #2
Ruby and Ruby on Rails: Tips and Tricks #3
Ruby and Ruby on Rails: Tips and Tricks #4
Ruby and Ruby on Rails: Tips and Tricks #5

Table of Contents

  1. Making String Equality Checks Readable with Rails’ #inquiry Method
  2. Understanding the Differences: Exploring Ruby’s .tap, .map, and .each Methods
  3. The Power of .pluck Method in Ruby on Rails
  4. Using ||= Operator in Ruby
  5. Exploring the Power of (*) and (**) in Ruby
  6. Generating Arrays of Alphabets or Numbers Using Ranges in Ruby

1. Making String Equality Checks Readable with Rails’ #inquiry Method

In Ruby on Rails, string equality checks can sometimes become cumbersome and less readable due to the use of multiple conditions and complex logic. Thankfully, Rails provides a helpful method called #inquiry that simplifies string equality checks, making your code more concise and easier to understand.

Understanding the Problem

Traditional string equality checks in Rails often involve multiple if or case statements, which can make the code verbose and harder to maintain. For instance, consider the following example:

status = "pending"
if status == "pending" || status == "in_progress"
# Perform some action
end

The code above checks if the status is either "pending" or "in_progress" before performing a specific action. While it works, it can be improved for better readability.

Introducing the #inquiry Method

Rails’ #inquiry method simplifies string equality checks by converting strings into inquiry objects. An inquiry object provides methods that allow for clearer and more expressive conditionals. Let's see how it works:

require 'active_support/core_ext/string/inquiry'

status = "pending".inquiry

if status.pending? || status.in_progress?
# Perform some action
end

By applying the #inquiry method to the string, we create an inquiry object that provides boolean methods for each possible value of the string. Now, the code reads more intuitively and is easier to follow.

Streamlining Array Equality Checks

Rails’ #inquiry method can also be extended to simplify array equality checks. Consider the following example:

require 'active_support/core_ext/array/inquiry'

tags = ["ruby", "rails", "web"].inquiry

if tags.ruby? || tags.javascript?
puts "This project involves Ruby or JavaScript."
end

When using #inquiry, it is important to note that it is an extension provided by ActiveSupport, which is a part of Ruby on Rails. Therefore, you need to ensure that the relevant ActiveSupport extensions are properly included or required in your code.

ActiveSupport::ArrayInquirer

ActiveSupport::ArrayInquirer for simplifying array equality checks in a Ruby on Rails application:

require 'active_support/all'

class User
ROLES = %w[admin user].freeze

def initialize(roles)
@roles = ActiveSupport::StringInquirer.new(roles)
end

def admin?
roles.admin?
end

def user?
roles.user?
end

private

attr_reader :roles
end

user = User.new('admin')
puts user.admin? # Output: true
puts user.user? # Output: false

In this example, we have a User class with a roles attribute. By utilizing ActiveSupport::StringInquirer, we simplify the conditionals for checking the user's roles, making the code more readable.

By incorporating ActiveSupport::ArrayInquirer into your Ruby on Rails application, you can simplify and improve the readability of array equality checks, making your code more maintainable and expressive.

2. Understanding the Differences: Exploring Ruby’s .tap, .map, and .each Methods

In Ruby programming, developers often come across the .tap, .map, and .each methods. While they may seem similar at first glance, these methods serve different purposes and have distinct functionalities.

#tap Method

The .tap method allows you to perform operations on an object within a block and return the original object itself. It comes in handy when you want to modify or inspect an object during a chain of operations without changing the final return value. Consider the following example:

name = "John"
name.tap { |n| n.upcase! }.reverse
# Output: "NHOJ"

In the example above, .tap modifies the original name object by applying the upcase! method, but the return value of .tap is still the original name. This allows us to chain further operations, such as .reverse, without affecting the original object.

#map Method

The .map method is used to transform elements in a collection and create a new array containing the transformed values. It applies a specified block of code to each element, collecting the results in a new array. Consider this example:

numbers = [1, 2, 3, 4, 5]
squared_numbers = numbers.map { |num| num * num }
# Output: [1, 4, 9, 16, 25]

In the above example, .map applies the block of code num * num to each element in the numbers array, creating a new array squared_numbers with the squared values.

#each Method

The .each method allows you to iterate over elements in a collection and perform specific actions or operations on each element. Unlike .map, it does not modify the collection or return a new array. Let's see an example:

fruits = ["apple", "banana", "orange"]
fruits.each { |fruit| puts fruit.capitalize }
# Output:
# "Apple"
# "Banana"
# "Orange"

In the above example, .each iterates over each element in the fruits array, applying the block of code puts fruit.capitalize to capitalize and output each fruit name.

Understanding the differences between .tap, .map, and .each is essential in leveraging their unique functionalities. Remember that .tap allows you to modify or inspect objects while maintaining the original value, .map transforms elements and returns a new array, and .each is used for iterating over elements without modifying the collection or creating a new array.

3. The Power of .pluck Method in Ruby on Rails

In its simplest form, the .pluck method allows you to fetch a single attribute from a collection of records. Instead of retrieving the entire objects from the database, you can use .pluck to directly fetch only the attribute you need. This reduces memory usage and speeds up your application.

Let’s dive into an example to see the .pluck method in action. Imagine you have a model called “User” with attributes like “id,” “name,” “email,” and “age.” If you want to retrieve only the names of all users, you can use the following line of code:

names = User.pluck(:name)
# User Load (0.5ms) SELECT `users`.`name` FROM `users`
# ["John Doe", "Jane Smith", "Mike Johnson", ...]

In this code snippet, User.pluck(:name) fetches the “name” attribute from the User model and assigns it to the names variable. The .pluck method automatically generates a SQL query behind the scenes, efficiently retrieving only the names from the database. The result is an array containing all the names of the users.

The .pluck method is not limited to fetching a single attribute. You can also use it to fetch multiple attributes simultaneously. Let’s say you want to retrieve both the names and emails of all users. Here’s how you can do it:

users_data = User.pluck(:name, :email)
# [["John Doe", "john@example.com"], ["Jane Smith", "jane@example.com"], ...]

In this case, User.pluck(:name, :email) retrieves the “name” and “email” attributes from the User model and assigns them to the users_data variable. The result is an array of arrays, where each inner array contains the name and email of a user.

The .pluck method is particularly useful when you’re working with large datasets or when you need to optimize the performance of your queries. By fetching only the necessary attributes, you reduce the amount of data transferred between the database and your application, resulting in faster query execution and improved response times.

It’s worth noting that the .pluck method is available in Ruby on Rails versions 4.1 and above. If you’re using an older version, you can achieve similar functionality with the .select method combined with the .map method. However, the .pluck method provides a more concise and efficient solution.

4. Using ||= Operator in Ruby

The ||= operator in Ruby is a powerful tool that allows for simple and concise conditional assignments. It’s commonly used when you want to assign a value to a variable only if it doesn’t already have a value.

It is equivalent to the following:

a || a = b

The beauty of the ||= operator lies in its simplicity. It saves you from writing explicit if-else statements and condenses the assignment logic into a single line. The operator checks if the variable has a value, and if it doesn’t, it assigns the value on the right-hand side. If the variable already has a value, the assignment doesn’t occur, preserving the existing value.

For example, the following code will set the variable x to 10 if it is currently false or nil:

x ||= 10

If x is already set to a value, then this code will do nothing.

When should I use ||= in Ruby?

You should use ||= in Ruby when you want to set the value of a variable to a certain value if the variable is currently false or nil. For example, you could use ||= to set the value of a variable to a default value if it is not already set.

Here are some examples of ||= in Ruby:

# Set the variable x to 10 if it is currently false or nil.
x ||= 10

# Set the variable y to the value of the variable z if z is not nil.
y ||= z

# Set the variable a to the value of the variable b if b is not false.
a ||= b

In conclusion, the ||= operator in Ruby provides simplicity and flexibility when it comes to conditional assignments.

5. Unlocking Method Flexibility: Exploring the Power of (*) and (**) in Ruby

In Ruby, the * and ** operators have a special significance when it comes to defining and using methods. They provide powerful capabilities for handling variable arguments and passing keyword arguments. Understanding the differences between them is key to writing flexible and expressive code.

The asterisk (*) operator in Ruby methods is commonly known as the “splat” operator. It allows for the handling of variable-length arguments, also known as varargs. By using the splat operator, you can create methods that accept an arbitrary number of arguments. Let’s delve into an example to see the * operator in action:

def greet(*names)
names.each do |name|
puts "Hello, #{name}!"
end
end

greet("Alice", "Bob", "Charlie")

In this code snippet, we define the greet method with the *names parameter. This allows the method to accept any number of arguments. Inside the method, we iterate over the names array and greet each person individually. When we call greet("Alice", "Bob", "Charlie"), the output will be:

Hello, Alice!
Hello, Bob!
Hello, Charlie!

The double asterisk (**) operator in Ruby methods is used for handling keyword arguments, often referred to as “keyword splats.” It enables the passing of a variable number of named arguments to a method. Let’s explore an example to understand the ** operator better:

def create_person(**details)
puts "Creating a person with the following details:"
puts "Name: #{details[:name]}"
puts "Age: #{details[:age]}"
end

create_person(name: "Alice", age: 25)

In this code snippet, we define the create_person method with the **details parameter. This allows the method to accept multiple keyword arguments. Inside the method, we access the specific details using the provided keys. When we call create_person(name: "Alice", age: 25), the output will be:

Creating a person with the following details:
Name: Alice
Age: 25

Now that we have seen examples of both * and ** operators in Ruby methods, let’s clarify the key differences between them:

  1. Functionality: The * operator handles variable-length arguments, enabling methods to accept any number of positional arguments and store them in an array. The ** operator handles keyword arguments, allowing methods to accept a variable number of named arguments and store them in a hash-like structure.
  2. Usage: The * operator is used in method definitions to capture variable-length arguments. It can also be used to spread an array or unpack an array into individual arguments. The ** operator is specifically used for handling keyword arguments and capturing them as a hash.
  3. Operator Placement: The * operator appears before the parameter name in the method definition, such as *names or *args. The ** operator appears before the parameter name and is followed by the double asterisks, such as **details or **kwargs.

By understanding the differences between the * and ** operators in Ruby methods, you can leverage their power effectively to create versatile and flexible code. Whether you’re handling variable-length arguments or working with keyword arguments, these operators offer powerful capabilities.

6. Generating Arrays of Alphabets or Numbers Using Ranges in Ruby

In Ruby, ranges provide a convenient way to generate arrays of alphabets or numbers. They allow you to define a sequence of values and easily convert them into arrays. Let’s explore how ranges can be used to generate arrays and provide simple examples.

Generating an array of alphabets:

alphabets = ('A'..'Z').to_a
puts alphabets.inspect

In this example, we create a range from ‘A’ to ‘Z’. By calling .to_a on the range, we convert it into an array of alphabets. The output will be:

["A", "B", "C", ..., "Z"]

Here, the range covers all uppercase alphabets from ‘A’ to ‘Z’, and the resulting array contains each alphabet as a separate element.

Generating an array of numbers:

numbers = (1..10).to_a
puts numbers.inspect

In this example, we create a range from 1 to 10. By converting it to an array using .to_a, we obtain an array of numbers from 1 to 10. The output will be:

[1, 2, 3, ..., 10]

Here, the range covers all integers from 1 to 10, and the resulting array contains each number as a separate element.

Ranges provide flexibility, allowing you to specify different start and end points. You can even define a step value to skip certain elements within the range. Let’s consider an example where we generate an array of even numbers:

evens = (2..20).step(2).to_a
puts evens.inspect

In this case, we create a range from 2 to 20 and use .step(2) to specify a step value of 2. By converting the range to an array, we generate an array of even numbers from 2 to 20. The output will be:

[2, 4, 6, ..., 20]

Here, the range covers even numbers from 2 to 20, and the resulting array contains each even number as a separate element.

Previous: Ruby and Ruby on Rails: Tips and Tricks #3
Next: Ruby and Ruby on Rails: Tips and Tricks #5

Erim Icel
LinkedInTwitterGithub

--

--