Code Monkey home page Code Monkey logo

dynamic-orm-inheritance's Introduction

Dynamic ORM with Inheritance

Objectives

  • Explain why it is useful to have an ORM class from which other classes in your program can inherit
  • Describe the code that is used to construct such a class

Why Inheritance?

The great thing about a Dynamic ORM is that it provides us with a way to write an ORM that is almost entirely abstract. In other words, the methods we write that allow a given Ruby class and instances to communicate with a database are not specific to any one class.

This means we can use such methods again and again. We can define them in only one place and simply make them available, via inheritance, to any other class in our program.

The Super Class

In this repo, in the lib directory, you'll see the interactive_record.rb file. Open it up and take a look.

You'll see that the InteractiveRecord class contains almost all of the code responsible for communicating between our Ruby program and our database. All of the methods defined there are abstract––they do not reference explicit class or attribute names nor do they reference explicit table or column names.

These are methods that can be used by any Ruby class or instance, as long as we make them available to that class or instance.

The Child Class

Go ahead and open up lib/song.rb. Notice that the Song class inherits from InteractiveRecord. This means that all of the methods defined in InteractiveRecord are available to Song.

require_relative "./interactive_record.rb"

class Song < InteractiveRecord

  self.column_names.each do |col_name|
    attr_accessor col_name.to_sym
  end

end

The only code the Song class needs to contain is the code to create the attr_accessors specific to itself. But even that code uses a method, #column_names, inherited from the super class.

Our Code in Action

Open up the executable file in bin/run.

song = Song.new(name: "Hello", album: "25")
puts "song name: " + song.name
puts "song album: " + song.album
song.save

puts Song.find_by_name("Hello")

Here we create a new Song instance. Remember, there was no initialize method defined in the Song class itself -- it is inherited from the InteractiveRecord class.

After the Song instance is created, information about the song's name and album is printed out with puts. The song instance is then saved to the database.

Just to make sure everything is working, Song.find_by_name("Hello") is used to search the database for the newly created song. When ruby bin/run is run in your terminal, it should produce the following, confirming that the song was saved:

song name: Hello
song album: 25
{"id"=>1, "name"=>"Hello", "album"=>"25"}

The #initialize, #save and #find_by_name methods used by Song here were inherited from InteractiveRecord.

Looking Ahead

As we begin to build complex web applications using Sinatra and Rails, this pattern of inheritance will become familiar. In fact, we'll use an ORM tool called Active Record that handles all of the ORM interactions for us, and we'll simply inherit our Ruby classes from Active Record's classes.

dynamic-orm-inheritance's People

Contributors

alexbarron avatar annjohn avatar aturkewi avatar aviflombaum avatar curiositypaths avatar drakeltheryuujin avatar emilycroft avatar franknowinski avatar gj avatar ihollander avatar jakebrady5 avatar jjseymour avatar maxwellbenton avatar pletcher avatar sophiedebenedetto avatar

Watchers

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

dynamic-orm-inheritance's Issues

./bin/run doesn't work

[23:46:37] (master) dynamic-orm-inheritance-online-web-pt-031119
// ♥ ./bin/run
song name: Hello
song album: 25
Traceback (most recent call last):
8: from ./bin/run:13:in <main>' 7: from /Users/leeyadavis/Development/LearnLabs/dynamic-orm-inheritance-online-web-pt-031119/lib/interactive_record.rb:53:in find_by_name'
6: from /Users/leeyadavis/.rvm/gems/ruby-2.6.1/gems/sqlite3-1.3.13/lib/sqlite3/database.rb:137:in execute' 5: from /Users/leeyadavis/.rvm/gems/ruby-2.6.1/gems/sqlite3-1.3.13/lib/sqlite3/database.rb:95:in prepare'
4: from /Users/leeyadavis/.rvm/gems/ruby-2.6.1/gems/sqlite3-1.3.13/lib/sqlite3/database.rb:138:in blockin execute' 3: from /Users/leeyadavis/.rvm/gems/ruby-2.6.1/gems/sqlite3-1.3.13/lib/sqlite3/statement.rb:37:in bind_params'
2: from /Users/leeyadavis/.rvm/gems/ruby-2.6.1/gems/sqlite3-1.3.13/lib/sqlite3/statement.rb:37:in each' 1: from /Users/leeyadavis/.rvm/gems/ruby-2.6.1/gems/sqlite3-1.3.13/lib/sqlite3/statement.rb:41:in blockin bind_params'
/Users/leeyadavis/.rvm/gems/ruby-2.6.1/gems/sqlite3-1.3.13/lib/sqlite3/statement.rb:41:in `bind_param': column index out of range (SQLite3::RangeException)

self.find_by_name causes column error

Saw the following error when running puts Song.find_by_name("Hello") from bin/run:

Traceback (most recent call last):
8: from bin/run:47:in <main>' 7: from /Users/aaronparkening/Dev/Flatiron/code/dynamic-orm-inheritance-online-web-pt-041519/lib/interactive_record.rb:55:in find_by_name'
6: from /Users/aaronparkening/.rvm/gems/ruby-2.6.1/gems/sqlite3-1.3.13/lib/sqlite3/database.rb:137:in execute' 5: from /Users/aaronparkening/.rvm/gems/ruby-2.6.1/gems/sqlite3-1.3.13/lib/sqlite3/database.rb:95:in prepare'
4: from /Users/aaronparkening/.rvm/gems/ruby-2.6.1/gems/sqlite3-1.3.13/lib/sqlite3/database.rb:138:in block in execute' 3: from /Users/aaronparkening/.rvm/gems/ruby-2.6.1/gems/sqlite3-1.3.13/lib/sqlite3/statement.rb:37:in bind_params'
2: from /Users/aaronparkening/.rvm/gems/ruby-2.6.1/gems/sqlite3-1.3.13/lib/sqlite3/statement.rb:37:in each' 1: from /Users/aaronparkening/.rvm/gems/ruby-2.6.1/gems/sqlite3-1.3.13/lib/sqlite3/statement.rb:41:in block in bind_params'
/Users/aaronparkening/.rvm/gems/ruby-2.6.1/gems/sqlite3-1.3.13/lib/sqlite3/statement.rb:41:in `bind_param': column index out of range (SQLite3::RangeException)

Directly running the SQL query completes correctly.

sql = "SELECT * FROM songs WHERE name = 'Hello'"
puts DB[:conn].execute(sql)

Bin/rub file is referring to a wrong database.

bin/rub file


require 'sqlite3'

Original file :
Line 4: DB = {:conn => SQLite3::Database.new("db/students.db")}
Should be DB = {:conn => SQLite3::Database.new("db/songs.db")} .

Other wise would raise an error "dynamic-orm-inheritance-web-0616/config/environment.rb:4:in `initialize': unable to open database file (SQLite3::CantOpenException)"

bin/run fails to execute

Getting all sorts of errors when trying to execute bin/run

bin/run: line 1: require: command not found
bin/run: line 3: require_relative: command not found
bin/run: line 4: require_relative: command not found
bin/run: line 5: require_relative: command not found
bin/run: line 7: syntax error near unexpected token (' bin/run: line 7: song = Song.new(name: "Hello", album: "25")'

Spec

Are there meant to be spec tests in this lab?

Permission error in bin/run

Track: Full Stack Web Development

Issue Summary: Student was having an issue with bin/run. I was expecting the code to output:

song name: Hello
song album: 25
{"id"=>1, "name"=>"Hello", "album"=>"25", 0=>1, 1=>"Hello", 2=>"25"}

but instead got:

-bash: bin/run: Permission denied

Files: bin/run

Branch: master

Issue Details

$ bin/run
-bash: bin/run: Permission denied

The permissions for this file seem to be configured incorrectly:

$ cd bin
$ ls -l
-rw-r--r-- 1 mattcassara staff 341 Nov 13 12:41 run

Also, the environment was not declared in run, which appeared to be contributing to the error as well:

#!/usr/bin/env ruby

Adjusting the permissions and adding that line of code seemed to fix this:

$ chmod 750 bin/run
$ bin/run
song name: Hello
song album: 25
{"id"=>1, "name"=>"Hello", "album"=>"25", 0=>1, 1=>"Hello", 2=>"25"}

@aturkewi

can't actually do the run- no gem file produces the following error

/Users/willley/Desktop/Class Work/dynamic-orm-inheritance-dc-web-060418/config/environment.rb:4:in initialize': unable to open database file (SQLite3::CantOpenException) from /Users/willley/Desktop/Class Work/dynamic-orm-inheritance-dc-web-060418/config/environment.rb:4:in new'
from /Users/willley/Desktop/Class Work/dynamic-orm-inheritance-dc-web-060418/config/environment.rb:4:in <top (required)>' from /Users/willley/Desktop/Class Work/dynamic-orm-inheritance-dc-web-060418/lib/interactive_record.rb:1:in require_relative'
from /Users/willley/Desktop/Class Work/dynamic-orm-inheritance-dc-web-060418/lib/interactive_record.rb:1:in <top (required)>' from run:4:in require_relative'
from run:4:in `

'

Unclear reference to #create

What is meant by: "The #create, #save and #find_by_name methods used here were inherited by Song from InteractiveRecord." ?

That is, where is the reference to #create?

Syntax Error line 52 interactive_record.rb

Line 52 of interactive_record.rb has a syntax error, with quotations around the question mark that break the code.

Specifically

sql = "SELECT * FROM #{self.table_name} WHERE name = '?'"

should be

sql = "SELECT * FROM #{self.table_name} WHERE name = ?"

bin/run Output Doesn't Match Lab Description

When running bin/run in this lab, the lab README advises that the output should be:

song = Song.new(name: "Hello", album: "25")
puts "song name: " + song.name
puts "song album: " + song.album
song.save

DB[:conn].execute("SELECT * FROM songs")

However, what I am getting is:

song name: Hello
song album: 25
Traceback (most recent call last):
8: from bin/run:13:in <main>' 7: from /home/renojames/dynamic-orm-inheritance-v-000/lib/interactive_record.rb:53: in find_by_name'
6: from /usr/local/rvm/gems/ruby-2.6.1/gems/sqlite3-1.4.0/lib/sqlite3/database.rb:1
93:in execute' 5: from /usr/local/rvm/gems/ruby-2.6.1/gems/sqlite3-1.4.0/lib/sqlite3/database.rb:1 51:in prepare'
4: from /usr/local/rvm/gems/ruby-2.6.1/gems/sqlite3-1.4.0/lib/sqlite3/database.rb:1
94:in block in execute' 3: from /usr/local/rvm/gems/ruby-2.6.1/gems/sqlite3-1.4.0/lib/sqlite3/statement.rb: 37:in bind_params'
2: from /usr/local/rvm/gems/ruby-2.6.1/gems/sqlite3-1.4.0/lib/sqlite3/statement.rb:
37:in each' 1: from /usr/local/rvm/gems/ruby-2.6.1/gems/sqlite3-1.4.0/lib/sqlite3/statement.rb: 41:in block in bind_params'
/usr/local/rvm/gems/ruby-2.6.1/gems/sqlite3-1.4.0/lib/sqlite3/statement.rb:41:in `bind_para
m': bind or column index out of range (SQLite3::RangeException)

String interpolation issue on line 52

of lib/interactive_record.rb

Wouldn't it be better if it was this:
def self.find_by_name(name)
sql = "SELECT * FROM #{self.table_name} WHERE name = '?'"
DB[:conn].execute(sql, name)
end

Unable to run bin/run

As you go through the follow along you are asked to run the bin file. I get this error:

// ♥ ruby bin/run
song name: Hello
song album: 25
Traceback (most recent call last):
8: from bin/run:13:in <main>' 7: from /home/TonyB/dynamic-orm-inheritance-online-web-pt-031119/lib/interactive_re cord.rb:53:in find_by_name'
6: from /usr/local/rvm/gems/ruby-2.6.1/gems/sqlite3-1.4.1/lib/sqlite3/database.rb:1
93:in execute' 5: from /usr/local/rvm/gems/ruby-2.6.1/gems/sqlite3-1.4.1/lib/sqlite3/database.rb:1 51:in prepare'
4: from /usr/local/rvm/gems/ruby-2.6.1/gems/sqlite3-1.4.1/lib/sqlite3/database.rb:1
94:in block in execute' 3: from /usr/local/rvm/gems/ruby-2.6.1/gems/sqlite3-1.4.1/lib/sqlite3/statement.rb: 37:in bind_params'
2: from /usr/local/rvm/gems/ruby-2.6.1/gems/sqlite3-1.4.1/lib/sqlite3/statement.rb:
37:in each' 1: from /usr/local/rvm/gems/ruby-2.6.1/gems/sqlite3-1.4.1/lib/sqlite3/statement.rb: 41:in block in bind_params'
/usr/local/rvm/gems/ruby-2.6.1/gems/sqlite3-1.4.1/lib/sqlite3/statement.rb:41:in `bind_para
m': bind or column index out of range (SQLite3::RangeException)

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.