Topic Review - learn-co-curriculum/pokemon-scraper GitHub Wiki

Welcome to the pokemon-scraper wiki!

Pokemon Scraper Lab Review

  • The purpose of the setup code is to get you to the important part of the lab which is SQL and Mapping your Class to the DB.
  • Focus on the Pokemon.rb file by creating the methods that save and find Pokemon in the DB.

Setup Code

Here is the setup code to help get you going.

scraper.rb

  • This class scrapes the Pokemon page. This class should ONLY scrape. You should call methods on the Pokemon class to Save/Create each Pokemon.
class Scraper
  attr_accessor :file, :parsed_file, :all_pokemon, :db

  def initialize(db)
    self.db = db
    self.file = File.open("pokemon_index.html")
    self.parsed_file = Nokogiri::HTML.parse(file)
    self.all_pokemon = catch_em_all
  end

  # this method is necessary to make the solution cooler.
  def catch_em_all
    self.all_pokemon = parsed_file.css(".infocard-tall")
  end

  def get_pokemon_name_from(node)
    node.css(".ent-name").text
  end

  def get_pokemon_type_from(node)
    node.css(".itype").text
  end

  def scrape
    all_pokemon.each do |pk_node|
      pk_name = get_pokemon_name_from(pk_node)
      pk_type = get_pokemon_type_from(pk_node)
      Pokemon.save(pk_name, pk_type, db)
    end
  end
end

SPEC

Before going into the pokemon.rb file, you'll need to write some SQL in the specs. Feel free to go through this quickly if the students are picking it up. Let them know that it's important to write the tests first, then make them pass.

pokemon.rb

  • This file holds the Pokemon class and Class Methods used to create and find Pokemon. ** This is where we will link the Database to our model. The commented out code is what you should build with the students. Emphasize on Sanitizing the statements.
class Pokemon
  attr_accessor :id, :name, :type, :hp, :db

# def self.save(name, type, db)
#    db.execute("INSERT INTO pokemon (name, type) VALUES (?, ?)", name, type)
# end

# def self.find(id_num, db)
#   pokemon_info = db.execute("SELECT * FROM pokemon WHERE id=?", id_num).first
#   Pokemon.new(pokemon_info, db)
# end

  def initialize(attr_array, db)
    @id, @name, @type, @hp = *attr_array
    @db = db
  end

  # def alter_hp(new_hp)
  #   db.execute("UPDATE pokemon SET hp = ? WHERE id = ?", new_hp, id)
  # end
end

schema_migration.sql

  • This file holds the SQL statement that creates the pokemon table.
CREATE TABLE IF NOT EXISTS pokemon(id INTEGER PRIMARY KEY AUTOINCREMENT, name TEXT, type TEXT);

Bonus Questions

  • First you must alter the table to add a HP column. ** Do this by creating a new sql file called alter_table_migration.sql
ALTER TABLE pokemon ADD hp integer NOT NULL DEFAULT(60);

The execute_create_hp_column method is used to execute the SQL statement inside of your .sql file

sql_runner.rb

  def execute_create_hp_column
    sql = File.read('db/alter_table_migration.sql')
    execute_sql(sql)
  end

The alter_hp method is used to update the HP of a pokemon in the DB. This is used when you battle Pokemon together.

pokemon.rb

  def alter_hp(new_hp)
    db.execute("UPDATE pokemon SET hp = ? WHERE id = ?", new_hp, id)
  end

DOUBLE BONUS

Build out more ActiveRecord methods for Pokemon - where returns an array of all the matching items, while destroy removes a single instance from the database.

pokemon.rb


  def self.all(db)
    pokemon = db.execute("SELECT * FROM posts")
    pokemon.map {|pokemon_info| Pokemon.new(pokemon_info, db) }
  end

  def self.where(type, db)
    sql = <<-SQL
    SELECT * FROM pokemon WHERE type = ?
    SQL
    pokemon = db.execute(sql, type)
    pokemon.map {|pokemon_info| Pokemon.new(pokemon_info, db)}
  end

 def destroy(db)
   db.execute("DELETE FROM pokemon WHERE id = ?", self.id)
 end