DEV Community

Cover image for How to create own utility methods for your Rails application
Igor Kasyanchuk
Igor Kasyanchuk

Posted on

How to create own utility methods for your Rails application

Hello,

As a developer, I need from time to time to quickly execute SQL, or check something in DB, truncate a table, etc when I'm in the rails console.

You may already know about using ActiveRecord::Base.connection.execute("SQL query") solution, but I must admit I'm a lazy developer when it comes to doing routine tasks or things where I need to type long pieces of code. And actually a snippet of code above is not everything that you need to type, you may also need to add .to_a to see the result of the query.

I know the following rule:

laziness is the engine of progress!

So, I tried to solve my issue as a developer and create an open-source solution to use it from project to project: https://github.com/igorkasyanchuk/execute_sql

This is a demo of how it works:
Demo

I'll explain how it works.

Step of creation gem I'll skip, but basically you need to create a new gem (rails plugin new <name>).

Now we need to understand how to add our own method just in the rails console.

module ExecuteSql
  class Railtie < ::Rails::Railtie

    console do
      TOPLEVEL_BINDING.eval('self').extend ExecuteSql::ConsoleMethods
    end

  end
end

This is a piece of code from my gem. You can see that Rails provides a helper method console where you can pass the code which will be executed when you starting rails c.
In our case this is TOPLEVEL_BINDING.eval('self').extend ExecuteSql::ConsoleMethods.

In case you have wondered, what this top-level constant TOPLEVEL_BINDING is all about better to check sample of usage below:

a = 42
p binding.local_variable_defined?(:a) # => true
p TOPLEVEL_BINDING.local_variable_defined?(:a) # => true

def example_method
  p binding.local_variable_defined?(:a) # => false
  p TOPLEVEL_BINDING.local_variable_defined?(:a) # => true
end

example_method

More details about TOPLEVEL_BINDING you can find here.

[11] pry(main)> TOPLEVEL_BINDING.eval('self')
=> main
[12] pry(main)> TOPLEVEL_BINDING
=> #<Binding:0x0000000001350b00>

As you can see TOPLEVEL_BINDING.eval('self') is basically the context of our console app.

So the last thing for us to do is to extend the main app with our class methods from ExecuteSql::ConsoleMethods module, source code is here.

This module inside is responsible for queries DB, and basically I took most of the code from my other gem rails_db and printing results using terminal-table gem.

Now my life is easier :)

And I hope you can implement your own utility methods.

Top comments (0)