What is a ruby gem, how is it made, and what are the pros and cons with an example.
Tags: ruby, rubygems, rails, webdev
Published: 2023-02-09 17:09:59

## **Ruby gems**

---

RubyGems is a package manager for the Ruby programming language. It provides a standard format for distributing Ruby libraries (known as "gems") and a way to easily install, manage and update these gems in a Ruby application.

A gem is a self-contained package of code, assets, and documentation that can be used in a Ruby application. Gems typically provide additional functionality that is not part of the core Ruby language, such as libraries for connecting to databases, handling HTTP requests, and so on.

RubyGems makes it easy to find, install, and manage gems in a Ruby application. You simply specify the gems that your application depends on in a file called the Gemfile, and then use the bundle install command to download and install all the gems specified in the file. The bundle install command also resolves any dependencies between gems and ensures that the correct version of each gem is installed.

RubyGems also provides a way to share gems with others. You can publish a gem to the RubyGems.org repository, where other developers can easily find and install it in their applications.

RubyGems is an essential tool for many Ruby developers, as it allows them to quickly and easily add new functionality to their applications. It's also a great way for Ruby developers to share their code and contribute to the Ruby community.

Here is an example of a Gemfile:

```ruby
source 'https://rubygems.org'

gem 'rails', '~> 6.0.0'
gem 'sqlite3'
gem 'bcrypt', '~> 3.1.7'
```

In this example, the source line specifies the default source for gems, which is RubyGems.org. The gem lines specify the gems that the application depends on, along with version constraints.

**Pros of using Rails gems in SAAS (Software as a Service) applications:**

- Reusability: Rails gems are pre-built components that you can reuse in multiple applications. This saves time and effort, as you don't have to build everything from scratch.

- Quality assurance: Most popular Rails gems are well tested and maintained, so you can be confident that they will work as expected in your application.

- Community support: There is a large community of developers who contribute to and support Rails gems, so you can often find solutions to common problems or get help with integration.

- Improved functionality: Rails gems can provide additional functionality that is not part of the core Rails framework. This can help you add new features to your application faster and with less effort.

**Cons of using Rails gems in SAAS applications:**

- Dependency management: Using gems can lead to complex dependencies between different components of your application, which can make it difficult to upgrade or manage your application.

- Security: Some gems may have vulnerabilities or security risks, which can compromise the security of your application. It's important to regularly check for updates and to use trusted gems.

- Performance: Using too many gems or gems with poor performance can slow down your application and affect its overall performance. It's important to choose gems carefully and to monitor the performance of your application regularly.

- Compatibility: Some gems may not be compatible with your application or with other gems that you're using, which can cause problems. It's important to test and verify that all the gems you're using work together as expected.

In conclusion, using Rails gems can be a powerful way to enhance the functionality of your SAAS application, but it's important to be mindful of the potential drawbacks and to use gems responsibly.

**Example**

Here is a step-by-step guide on how to create a gem in Ruby on Rails based and install it in a Rails application:

1. Create a new directory for your gem: `mkdir photo_upload_gem`

2. Navigate to the newly created directory: `cd photo_upload_gem`

3. Initialize a new gem: `bundle gem photo_upload_gem`

4. Fill in the required information, such as the name, summary, and description of your gem.

5. Open the gemspec file: open photo_upload_gem.gemspec

6. Add the following code to include the necessary dependencies:

```ruby
# photo_upload_gem.gemspec

Gem::Specification.new do |s|
  # ...
  s.add_dependency 'paperclip'
end
```

7. Create a generator for your gem: `touch lib/generators/photo_upload_gem/install_generator.rb`

8. Add the following code to the generator to create the necessary files:

```ruby
# lib/generators/photo_upload_gem/install_generator.rb

class PhotoUploadGem::InstallGenerator < Rails::Generators::Base
  source_root File.expand_path("../templates", __FILE__)

  def create_model
    template 'photo.rb', 'app/models/photo.rb'
  end

  def create_controller
    template 'photos_controller.rb', 'app/controllers/photos_controller.rb'
  end

  def create_view
    template 'new.html.erb', 'app/views/photos/new.html.erb'
  end

  def add_routes
    route 'resources :photos, only: [:new, :create]'
  end
end
```

9. Create the templates for the model, controller, and view:` mkdir lib/generators/photo_upload_gem/templates`

10. Add the following code to the photo.rb template:

```ruby
# lib/generators/photo_upload_gem/templates/photo.rb

class Photo < ActiveRecord::Base
  has_attached_file :attachment
  validates_attachment_content_type :attachment, content_type: /\Aimage\/.*\Z/
end
```

11. Add the following code to the photos_controller.rb template:

```ruby
# lib/generators/photo_upload_gem/templates/photos_controller.rb

class PhotosController < ApplicationController
  def new
    @photo = Photo.new
  end

  def create
    @photo = Photo.new(photo_params)
    if @photo.save
      redirect_to root_path, notice: 'Photo was successfully uploaded.'
    else
      render :new
    end
  end

  private

  def photo_params
    params.require(:photo).permit(:attachment)
  end
end
```

12. Add the following code to the `new.html.erb` template:

```ruby
<!-- lib/generators/photo_upload_gem/templates/new.html.erb -->

<%= form_for @photo, html: { multipart: true } do |f| %>
  <%= f.file_field :attachment %>
  <%= f.submit %>
<% end %>
```

13. Build the gem: `bundle build photo_upload_gem`

14. Test the gem locally by installing it in a test application: `cd path/to/test/app && bundle install`

15. Add the following code to the Gemfile of your test application:

```ruby
# Gemfile

gem 'photo_upload_gem', path: 'path/to/photo_upload_gem'
```

16. Run the generator to create the necessary files:` rails generate photo_upload_gem:install`

17. Migrate the database to create the necessary tables: `rake db:migrate`

18. Visit http://localhost:3000/photos/new to test the photo upload feature.

---

**Accounting App Example**

Creating a gem and using it in a Rails application is a great way to encapsulate and reuse code across multiple projects. Here's a step-by-step guide to creating a gem for an accounting application and using it in a Rails application:


1. Generate the gem skeleton

- Open your terminal and navigate to the directory where you want to create your gem
- Run the following command to create the gem skeleton:
`$ bundle gem my_accounting_app`

This will create a directory named `my_accounting_app` with the basic structure of a Ruby gem.

2. Define the accounting methods

- In the lib directory, create a file named `my_accounting_app.rb`. This is where you'll define the methods for your accounting application.
- For example, you can create a method to calculate the total amount of an invoice:

```ruby
module MyAccountingApp
  def self.total_amount(amount, tax)
    amount + (amount * tax)
  end
end
```

3. Write the gemspec

- In the root directory of your gem, you'll find a file named `my_accounting_app.gemspec`. This is where you'll specify the metadata for your gem, such as its name, version, author, and description.
- Update the gemspec file with the following information:

```ruby
# my_accounting_app.gemspec
Gem::Specification.new do |spec|
  spec.name        = "my_accounting_app"
  spec.version     = "0.1.0"
  spec.authors     = ["Your Name"]
  spec.email       = ["your_email@example.com"]
  spec.summary     = "A gem for accounting applications"
  spec.description = "A gem that provides methods for accounting applications"
  spec.files       = Dir["lib/**/*.rb"]
  spec.require_paths = ["lib"]
end
```

4. Build the gem

- In the root directory of your gem, run the following command to build the gem:
`$ gem build my_accounting_app.gemspec`

- This will create a `.gem` file in the root directory of your gem, which you can use to install the gem.

5. Use the accounting methods in your Rails application

- Create a new Rails application: `$ rails new my_rails_app`
- Add the following line to the Gemfile of your Rails application:

```ruby
gem "my_accounting_app", path: "/path/to/my_accounting_app"
```

- Replace /path/to/my_accounting_app with the actual path to your gem.
- Run the following command to install the gem in your Rails application:  `$ bundle install`

6. Use the accounting methods in your Rails application

```ruby
class InvoicesController < ApplicationController
  def show
    amount = params[:amount].to_f
    tax = params[:tax].to_f
    @total_amount = MyAccountingApp.total_amount(amount, tax)
  end
end
```

- This code creates an instance variable @total_amount that holds the result of calling `MyAccountingApp.total_amount` with amount and tax from the URL parameters.
- You'll also need to add a route to map URLs to the `InvoicesController`:

```ruby
Rails.application.routes.draw do
  get "/invoices/show", to: "invoices#show"
end
```

You can use the total_amount method in your view to display the calculated amount:

```ruby
<h1>Invoice</h1>
<p>Amount: <%= params[:amount] %></p>
<p>Tax: <%= params[:tax] %></p>
<p>Total amount: <%= @total_amount %></p>
```

This view displays the amount and tax from the URL parameters and the calculated total amount from the controller.
You'll need to create a file app/views/invoices/show.html.erb with the above content.

`$ rails s`

Navigate to `http://localhost:3000/invoices/show?amount=100&tax=0.1` in your web browser to see the calculated total amount

7. Publish your gem to RubyGems

- If you want to make your gem available to others, you can publish it to RubyGems.org.
- First, you'll need to create an account on RubyGems.org.
- Then, run the following command to publish your gem:
`$ gem push my_accounting_app-0.1.0.gem`
- Replace my_accounting_app-0.1.0.gem with the actual name of your gem file.

That's it! You've successfully created a gem for an accounting application and used it in a Rails application. By encapsulating the accounting logic in a gem, you can reuse it across multiple projects and share it with others.