Code Monkey home page Code Monkey logo

phase-3-active-record-intro-to-rake's Introduction

Intro to Rake

Learning Goals

  • Introduce Rake and Rake tasks
  • Understand what Rake is used for in our Ruby programs
  • Learn how to build a basic Rake task

Introduction

Rake is a tool that is available to us in Ruby that allows us to automate certain jobs โ€” anything from executing SQL to puts-ing out a friendly message to the terminal.

Rake allows us to define something called Rake tasks that execute these jobs. Once we define a task, that task can be executed from the command line.

Rake tasks have a similar utility to npm scripts in JavaScript, which you'd see in the package.json file, like npm start or npm test. They give you an easy way to run common tasks from the command line.

Why Rake?

Every program has some tasks that must be executed now and then. For example, the task of creating a database table, or the task of making or maintaining certain files. Before Rake was invented, we would either have to write standalone bash scripts to accomplish these tasks, or each developer would have to make their own decisions about what segment of their Ruby program would be responsible for executing these tasks.

Writing scripts in bash is tough, plus bash just isn't as powerful as Ruby. And for each developer to make their own somewhat arbitrary decisions about where to define and execute certain common tasks related to databases or file maintenance would be confusing. Luckily, Rake provides us a standard, conventional way to define and execute such tasks using Ruby.

Where did Rake Come From?

The C community was the first to implement the pattern of writing all their recurring system maintenance tasks in a separate file. They called this file the MakeFile because it was generally used to gather all of the source files and make it into one compiled executable file.

Rake was later developed by Jim Weirich as the task management tool for Ruby.

How to Define and Use Rake Tasks

Building a Rake task is easy. All we need to do is create a file in the top level of our directory called Rakefile. Here we define our task:

task :hello do
  # the code we want to be executed by this task
end

We define tasks with task + name of task as a symbol + a block that contains the code we want to execute.

If you open up the Rakefile in this directory, you'll see our :hello task:

task :hello do
  puts "hello from Rake!"
end

Now, in your terminal in the directory of this project, type:

$ rake hello
hello from Rake!

You should see the text above outputted to your terminal.

Describing our Tasks With rake -T

Rake comes with a handy command, rake -T, that we can run in the terminal to view a list of available Rake tasks and their descriptions. In order for rake -T to work though, we need to give our Rake tasks descriptions. Let's give our hello task a description now:

desc 'outputs hello to the terminal'
task :hello do
  puts "hello from Rake!"
end

Now, if we run rake -T in the terminal, we should see the following:

$ rake -T
rake hello       # outputs hello to the terminal

So handy!

Namespacing Rake Tasks

It is possible to namespace your Rake tasks. What does "namespace" mean? A namespace is really just a way to group or contain something, in this case our Rake tasks. So, we might namespace a series of greeting Rake tasks, like hello above, under the greeting heading.

Let's take a look at namespacing now. Let's say we create another greeting-type Rake task, hola:

desc 'outputs hola to the terminal'
task :hola do
  puts "hola desde Rake!"
end

Now, let's namespace both hello and hola under the greeting heading:

namespace :greeting do
desc 'outputs hello to the terminal'
  task :hello do
    puts "hello from Rake!"
  end

  desc 'outputs hola to the terminal'
  task :hola do
    puts "hola desde Rake!"
  end
end

Now, to use either of our Rake tasks, we use the following syntax:

$ rake greeting:hello
hello from Rake!

$ rake greeting:hola
hola desde Rake!

bundle exec rake

One common issue with Rake is the following: you run a Rake task, like rake greeting:hello, and see an output like this:

$ rake greeting:hello
rake aborted!
Gem::LoadError: You have already activated rake 10.4.2,
but your Gemfile requires rake 10.4.0.
Prepending `bundle exec` to your command may solve this.

This is a very common thing to see as a Ruby developer, and luckily, there's an easy fix if you do happen to see this error message. Just follow the instructions, and "prepend" bundle exec to your rake command:

$ bundle exec rake greeting:hello
hello from Rake!

While it is a bit of extra typing, we can tell you from experience, it's worth the effort once you start encountering this issue. If you're curious as to why, check out this article:

We suggest you get in the habit of using bundle exec with your Rake commands.

Common Rake Tasks

As we move towards developing Sinatra and Rails web applications, you'll begin to use some common Rake tasks that handle certain database-related jobs. We'll be using a gem to set up some of these tasks for us, but it's still helpful to get an understanding of the syntax of Rake tasks so you can create your own.

rake db:migrate

One common pattern you'll soon become familiar with is the pattern of writing code that creates database tables and then "migrating" that code using a rake task.

Our Student class currently has a #create_table method, so let's use that method to build out our own migrate Rake task.

Note: This lesson doesn't use Active Record, so the functionality of interacting with the database is all handled within the Student class, like when we were creating our own ORMs.

We'll namespace this task under the db heading. This namespace will contain a few common database-related tasks.

We'll call this task migrate, because it is a convention to say we are "migrating" our database by applying SQL statements that alter that database.

namespace :db do
  desc 'migrate changes to your database'
  task migrate: :environment do
    Student.create_table
  end
end

But, if we run rake db:migrate now, we're going to hit an error:

rake aborted!
Don't know how to build task 'environment' (See the list of available tasks with `rake --tasks`)

Task Dependency

You might be wondering what is happening with this snippet:

task migrate: :environment do

This creates a task dependency. This line of code tells Rake that it needs to run the environment task before it can run migrate. The issue is that our Student.create_table code needs access to the config/environment.rb file because that's where the student class and database are loaded. Before we can migrate, we need to give our task access to this file, and the environment task is what will do this for us. But we haven't created the environment task yet, so let's do that.

Add the following code to the Rakefile:

task :environment do
  require_relative './config/environment'
end

Now, running bundle exec rake db:migrate should create our students table.

rake db:seed

Another task you will become familiar with is the seed task. This task is responsible for "seeding" our database with some placeholder data.

The conventional way to seed your database is to have a file in the db directory, db/seeds.rb, that contains some code to create instances of your class.

If you open up db/seeds.rb you'll see the following code to create a few students:

Student.create(name: "Melissa", grade: "10th")
Student.create(name: "April", grade: "10th")
Student.create(name: "Luke", grade: "9th")
Student.create(name: "Devon", grade: "11th")
Student.create(name: "Sarah", grade: "10th")

Then, we define a rake task that executes the code in this file. This task will also be namespaced under db:

namespace :db do

  # ...

  desc 'seed the database with some dummy data'
  task seed: :environment do
    require_relative './db/seeds'
  end
end

Now, if we run bundle exec rake db:seed in our terminal (provided we have already run rake db:migrate to create the database table), we will insert five records into the database.

If only there was some way to interact with our class and database without having to run our entire program...

Well, we can build a Rake task that will load up a Pry console for us.

rake console

We'll define a task that starts up the Pry console. We'll make this task dependent on our environment task so that the Student class and the database connection load first. Note that this class is not namespaced under :db, since we'll use it as a more general-purpose tool.

desc 'drop into the Pry console'
task console: :environment do
  Pry.start
end

Now, provided we ran rake db:migrate and rake db:seed, we can drop into our console with the following:

$ bundle exec rake console

This should bring you into a Pry session in your terminal:

[1] pry(main)>

Let's check to see that we did in fact successfully migrate and seed our database:

Student.all
# => [[1, "Melissa", "10th"],
#  [2, "April", "10th"],
#  [3, "Luke", "9th"],
#  [4, "Devon", "11th"],
#  [5, "Sarah", "10th"]]

We did it!

Conclusion

As developers, we are constantly iterating and experimenting on our code. To make our lives easier, it's helpful to use a tool like Rake to automate some of the common setup and testing tasks we need to run in order to interact with our applications. Using Rake is a great way to speed up your development process โ€” any time you find yourself running the same code over and over again, consider setting up a Rake task for it.

Resources

phase-3-active-record-intro-to-rake's People

Contributors

annjohn avatar dakotalmartinez avatar dandanberry avatar dependabot[bot] avatar devinburnette avatar franknowinski avatar gj avatar ihollander avatar lizbur10 avatar maxwellbenton avatar pletcher avatar sammarcus avatar sgharms avatar simque avatar sophiedebenedetto avatar victhevenot avatar

Stargazers

 avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

phase-3-active-record-intro-to-rake's Issues

deprecated language

Canvas Link

https://learning.flatironschool.com/courses/4980/assignments/169129?module_item_id=366662

Concern

This has been the case on the last few labs, but this is the first one where it's really a pain because it shows up every time we type something in the CLI. When i run 'bundle install' as well as every time I run a rake script, I get this:

Calling DidYouMean::SPELL_CHECKERS.merge!(error_name => spell_checker)' has been deprecated. Please call DidYouMean.correct_error(error_name, spell_checker)' instead.

Additional Context

No response

Suggested Changes

No response

Pry console task not working

I'm trying to use the console task to drop into a Pry console, but it's not working. I get the following error:

rake aborted!
Don't know how to build task 'environment' (See the list of available tasks with `rake --tasks`)
Did you mean?  db:environment

The correct code should be:

desc 'drop into the Pry console'
task :console do
require_relative './config/environment'
Pry.start
end

Last 'Pry' Based Rake Task Is Flawed

Canvas Link

https://learning.flatironschool.com/courses/5286/assignments/172676?module_item_id=376756

Concern

Here's my entire script:

# NOTE: If we then use the command, 'rake hello' in another terminal, we the return the 'puts' output below
# It's basically Ruby's version of the 'Makefile' / Crontab jobs

# NOTE: By adding a 'namespace', we can group our related Rake tasks together:
namespace :greeting do

  # NOTE: If we use 'rake -T', this will list the available 'Rake' tasks and their descriptions:
  desc 'outputs hello to the terminal'
  task :hello do
    puts "hello from Rake!"
  end

  desc 'outputs hola to the terminal'
  task :hola do
    puts "hola desde Rake!"
  end

end

# NOTE: We can use these individual tasks using the 'namespace:rake_task' syntax:
# rake greeting:hello
# rake greeting:hola

# NOTE: If you encounter this error:
# rake aborted!
# Gem::LoadError: You have already activated rake 10.4.2,
# but your Gemfile requires rake 10.4.0.
# Prepending `bundle exec` to your command may solve this.

# Then, use this command as the fix:
# bundle exec rake greeting:hello

# NOTE: We will now use the 'rake db:migrate' command to create a database table and migrate the code using
# a 'rake' task:

namespace :db do
  task :environment do
    require_relative "./config/environment"
  end

  desc "migrate changes to your database"
  # NOTE: This line creates a task dependency to force the rake task to run the ':environment' task
  # BEFORE running the 'migrate' task:
  task migrate: :environment do
    Student.create_table
  end

  desc "seed the database with some dummy data"
  task seed: :environment do
    require_relative "./db/seeds"
  end
end

desc "drop into the Pry console"
task console: :environment do
  Pry.start
end

If I run the 'bundle exec rake console' command after running the 'rake db:migrate' and 'rake db:seed' commands respectively, I get this error:

samuelbanya@Samuels-MBP ~/hub/Development/code/phase-3/phase-3-active-record-intro-to-rake $ bundle exec rake console
rake aborted!
Don't know how to build task 'environment' (See the list of available tasks with `rake --tasks`)
Did you mean?  db:environment
/Users/samuelbanya/.gem/gems/rake-13.0.6/exe/rake:27:in `<top (required)>'
/Users/samuelbanya/.gem/gems/bundler-2.2.23/lib/bundler/cli/exec.rb:63:in `load'
/Users/samuelbanya/.gem/gems/bundler-2.2.23/lib/bundler/cli/exec.rb:63:in `kernel_load'
/Users/samuelbanya/.gem/gems/bundler-2.2.23/lib/bundler/cli/exec.rb:28:in `run'
/Users/samuelbanya/.gem/gems/bundler-2.2.23/lib/bundler/cli.rb:474:in `exec'
/Users/samuelbanya/.gem/gems/bundler-2.2.23/lib/bundler/vendor/thor/lib/thor/command.rb:27:in `run'
/Users/samuelbanya/.gem/gems/bundler-2.2.23/lib/bundler/vendor/thor/lib/thor/invocation.rb:127:in `invoke_command'
/Users/samuelbanya/.gem/gems/bundler-2.2.23/lib/bundler/vendor/thor/lib/thor.rb:392:in `dispatch'
/Users/samuelbanya/.gem/gems/bundler-2.2.23/lib/bundler/cli.rb:30:in `dispatch'
/Users/samuelbanya/.gem/gems/bundler-2.2.23/lib/bundler/vendor/thor/lib/thor/base.rb:485:in `start'
/Users/samuelbanya/.gem/gems/bundler-2.2.23/lib/bundler/cli.rb:24:in `start'
/Users/samuelbanya/.gem/gems/bundler-2.2.23/exe/bundle:49:in `block in <top (required)>'
/Users/samuelbanya/.gem/gems/bundler-2.2.23/lib/bundler/friendly_errors.rb:128:in `with_friendly_errors'
/Users/samuelbanya/.gem/gems/bundler-2.2.23/exe/bundle:37:in `<top (required)>'
/Users/samuelbanya/.rvm/gems/ruby-2.7.4/bin/bundle:25:in `load'
/Users/samuelbanya/.rvm/gems/ruby-2.7.4/bin/bundle:25:in `<main>'
/Users/samuelbanya/.rvm/gems/ruby-2.7.4/bin/ruby_executable_hooks:22:in `eval'
/Users/samuelbanya/.rvm/gems/ruby-2.7.4/bin/ruby_executable_hooks:22:in `<main>'
Tasks: TOP => console
(See full trace by running task with --trace)

Additional Context

No response

Suggested Changes

No response

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.