thumbtackthief
thumbtackthief

Reputation: 6211

Ruby class expects class variable but only in Rake task

I am trying to seed my database with some dummy data, so I have this seed file:

db/seeds.rb

require 'require_all'
require_all 'lib'

Author.create(name: "Mark Twain")

My Ruby model and relevant methods:

lib/author.rb

class Author

    attr_accessor :name, :id

    def initialize(name, id=nil)
        @name = name
        @id = id
    end

    def self.make_object_from_row(row)
        # [1, "Mark Twain"]
        Author.new(row[1], row[0])
    end

    def self.create(name)
        author = Author.new(name)
        author.save
    end

    def save
        if self.id.nil?  # doesn't exist in the database yet
            sql = <<-SQL
                INSERT INTO authors (name)
                VALUES (?)
            SQL
            DB.execute(sql, self.name)
            sql = "SELECT last_insert_rowid()"
            self.id = DB.execute(sql)[0][0]
        else # just update the row in the db
            sql = <<-SQL
                UPDATE authors SET (name) = ? WHERE id = ?
            SQL
            DB.execute(sql, self.name, self.id)
        end
    end

Rakefile

require_relative './config/environment'

desc "Set up database"
task :db_setup do
    author_sql = <<-SQL
        CREATE TABLE IF NOT EXISTS authors(
            id integer PRIMARY KEY,
            name varchar(255)
        );
    SQL
    DB.execute(author_sql)
end

desc "Seed database"
task :db_seed do
    ruby "db/seeds.rb"
end

config/environment.rb

require 'bundler/setup'
Bundler.require

# setting up the database connection (old way)
DB = SQLite3::Database.new("db/development.db")

require_relative '../lib/author.rb'

When I run the rake task for db_seed I get the error . lib/author.rb:26:in save': uninitialized constant Author::DB (NameError)

The db_setup Rake task works fine. Also if I go into a pry from my console, I can instantiate a new Author without a problem (and it writes to the database). If I run the seed file from my command line, I get the same error.

I see that it's looking for an attribute DB on the Author class, but I don't see why, or why it's inconsistent in that I can create an Author from the command line but not from the Rake task--if the variable were undefined that shouldn't make a difference, correct?

(I'm also aware that using ActiveRecord would be much easier, but I'm not looking to use it right now)

Upvotes: 2

Views: 140

Answers (1)

tadman
tadman

Reputation: 211590

When you see errors like "uninitialized constant" popping up and you're sure you've defined that constant in a file somewhere, make sure you're loading that code in before the method with the error runs.

It looks like in this case config/environment wasn't loaded before DB was referenced, so it can't complete.

Due to how Ruby searches for constants it's presented as Author::DB because the code was running inside of the Author namespace and that's where searches start.

Upvotes: 2

Related Questions