Ruby on Rails with Modular Rails, ActiveRecord & Testing

Avatar

By squashlabs, Last Updated: Sept. 28, 2023

Ruby on Rails with Modular Rails, ActiveRecord & Testing

Modular Rails

Related Article: Techniques for Handling Large Data with Ruby on Rails

What is Modular Rails?

Modular Rails is an approach to building Ruby on Rails applications that emphasizes modularity and reusability. It involves breaking down the application into smaller, self-contained modules or engines that can be developed and tested independently. This modular architecture allows for easier maintenance, scalability, and code organization.

How to Build Engines and Modular Apps in Ruby on Rails?

To build engines and modular apps in Ruby on Rails, you can follow these steps:

1. Start a new Rails application or use an existing one.

2. Generate a new engine using the rails plugin new command. This will create a new directory structure for your engine.

3. Define the functionality and features of your engine by adding models, controllers, views, and other necessary files.

4. Mount the engine in your main Rails application by adding the engine's name to the config/routes.rb file.

5. Use the engine's functionality in your main Rails application by calling the engine's methods or accessing its models and controllers.

Here's an example of how to generate a new engine and mount it in a Rails application:

$ rails plugin new my_engine
$ cd my_engine

In the my_engine.gemspec file, specify the dependencies for your engine:

spec.add_dependency 'rails', '>= 6.0'

Create a new controller and add some functionality to it:

# app/controllers/my_engine/my_controller.rb
module MyEngine
  class MyController < ApplicationController
    def index
      @items = MyEngine::Item.all
    end
  end
end

Create a view for the controller:

<!-- app/views/my_engine/my/index.html.erb -->
<h1>My Engine Items</h1>

<ul>
  <% @items.each do |item| %>
    <li><%= item.name %></li>
  <% end %>
</ul>

Mount the engine in the main Rails application by adding the following line to config/routes.rb:

mount MyEngine::Engine, at: '/my_engine'

Now, you can access the functionality of the engine by visiting /my_engine/my in your browser.

ActiveRecord

Related Article: Ruby on Rails with Internationalization and Character Encoding

What is ActiveRecord and How to Effectively Manage Databases with It?

ActiveRecord is the object-relational mapping (ORM) component of Ruby on Rails. It provides an easy and intuitive way to interact with databases by mapping database tables to Ruby classes and their instances to table rows.

To effectively manage databases with ActiveRecord, you can use advanced scopes, queries, and raw SQL.

What are Advanced Scopes in Ruby on Rails?

Advanced scopes in Ruby on Rails allow you to define complex queries and filter conditions on your models. Scopes are similar to class methods but provide a more declarative and chainable syntax for building queries.

Here's an example of how to define an advanced scope in Ruby on Rails:

class User < ApplicationRecord
  scope :active, -> { where(active: true) }
  scope :admins, -> { where(role: 'admin') }
  scope :with_posts, -> { joins(:posts).distinct }

  def self.most_recent(limit)
    order(created_at: :desc).limit(limit)
  end
end

In this example, we have defined several scopes on the User model:

- The active scope returns all active users.

- The admins scope returns all users with the role of 'admin'.

- The with_posts scope returns all users who have at least one post.

- The most_recent scope is a class method that returns the most recent users based on their creation date.

You can then use these scopes in your queries and chain them together:

User.active.admins.with_posts.most_recent(10)

This will return the 10 most recent active users who are admins and have at least one post.

How to Use Raw SQL in Ruby on Rails?

While ActiveRecord provides a useful query interface, there may be cases where you need to execute raw SQL queries in your Ruby on Rails application. This can be useful for complex queries or when you need to leverage database-specific features.

To use raw SQL in Ruby on Rails, you can use the ActiveRecord::Base.connection.execute method. Here's an example:

sql = "SELECT * FROM users WHERE age > 18"
results = ActiveRecord::Base.connection.execute(sql)

results.each do |row|
  puts "#{row['name']}, #{row['age']}"
end

In this example, we execute a raw SQL query to select all users with an age greater than 18. The execute method returns a result object, which we can iterate over to access the rows returned by the query. You can access the columns of each row using their names as keys.

It's important to note that using raw SQL should be done with caution, as it bypasses some of the safety features provided by ActiveRecord, such as automatic sanitization of user input. Make sure to properly sanitize any user input before including it in a raw SQL query to prevent SQL injection vulnerabilities.

Testing with TDD

Related Article: Ruby on Rails Performance Tuning and Optimization

What is TDD and How Does It Go Beyond the Basics with RSpec in Ruby on Rails?

Test-Driven Development (TDD) is a software development approach that emphasizes writing tests before writing the actual code. It follows a cycle of writing a failing test, writing the code to make the test pass, and then refactoring the code.

RSpec is a popular testing framework for Ruby on Rails that provides a rich set of tools for writing tests. It goes beyond the basics of testing by offering advanced features such as test doubles, custom matchers, and hooks for before/after actions.

Here's an example of how TDD with RSpec can go beyond the basics in Ruby on Rails:

# spec/models/user_spec.rb
RSpec.describe User, type: :model do
  describe '#full_name' do
    it 'returns the full name of the user' do
      user = User.new(first_name: 'John', last_name: 'Doe')

      expect(user.full_name).to eq('John Doe')
    end
  end
end

In this example, we write a test for the full_name method of the User model. We create a new user object with a first name of 'John' and a last name of 'Doe'. We then expect the full_name method to return 'John Doe'. If the test fails, we write the code necessary to make it pass.

TDD with RSpec allows you to have a comprehensive suite of tests that cover all aspects of your application, ensuring that your code works as expected and is well-maintained.

Testing with BDD

What is BDD and How Does It Go Beyond the Basics with Cucumber in Ruby on Rails?

Behavior-Driven Development (BDD) is a software development approach that focuses on the behavior and requirements of the system rather than the implementation details. It encourages collaboration between developers, testers, and business stakeholders to ensure that the software meets the desired behavior.

Cucumber is a popular tool for implementing BDD in Ruby on Rails. It allows you to write executable specifications in plain text using the Gherkin language. These specifications, also known as feature files, describe the expected behavior of the system in a human-readable format.

Here's an example of how BDD with Cucumber can go beyond the basics in Ruby on Rails:

# features/user_management.feature
Feature: User Management
  As a user
  I want to be able to manage my account
  So that I can update my profile information

  Scenario: Update user profile
    Given I am logged in as a user
    When I visit the edit profile page
    And I fill in the form with valid information
    And I click the "Update" button
    Then I should see a success message
    And my profile should be updated

  Scenario: Invalid form submission
    Given I am logged in as a user
    When I visit the edit profile page
    And I fill in the form with invalid information
    And I click the "Update" button
    Then I should see an error message
    And my profile should not be updated

In this example, we define two scenarios in the user_management.feature file. Each scenario describes a specific behavior of the user management feature. The steps in the scenario are implemented using step definitions, which map the plain text steps to Ruby code.

BDD with Cucumber allows you to have a common language that can be understood by all stakeholders, enabling effective communication and collaboration. It also provides a clear definition of the expected behavior of the system, making it easier to write tests and ensure that the software meets the desired specifications.

Additional Resources



- Ruby on Rails Tutorial: Learn Web Development with Rails - Chapter 3: MVC and REST

- Ruby on Rails Guides: Authentication and Authorization

- Devise Gem Documentation: Getting Started

You May Also Like

Ruby on Rails with SSO, API Versioning & Audit Trails

Setting up Single Sign-On (SSO), API versioning, and audit trails in Ruby on Rails can be a complex task. However, with the right knowledge and tools… read more

Ruby on Rails with Bootstrap, Elasticsearch and Databases

Integrate Bootstrap, Elasticsearch, and databases with Ruby on Rails. Learn how to style Rails apps with Bootstrap, connect Rails with popular databa… read more

Ruby on Rails with WebSockets & Real-time Features

This tutorial delves into the use of ActionCable in building real-time features in Rails, such as chat and notifications. The article explores the ro… read more