Skip to content

Instantly share code, notes, and snippets.

@rikas
Created February 12, 2020 19:58
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save rikas/2cb18fc5c1fbf459eb009339c8418578 to your computer and use it in GitHub Desktop.
Save rikas/2cb18fc5c1fbf459eb009339c8418578 to your computer and use it in GitHub Desktop.
Record to be used like the ActiveRecord::Base class
# You can use a global variable, DB, which
# is an instance of SQLite3::Database
# NO NEED TO CREATE IT, JUST USE IT.
require 'sqlite3'
require 'pry-byebug'
db_file_path = File.join(File.dirname(__FILE__), "../../spec/support/posts_spec.db")
DB = SQLite3::Database.new(db_file_path)
DB.results_as_hash = true
class Record
def self.inherited(base)
base_table_name = "#{base.name.downcase.split(/\s/).join('_')}s"
base.class.class_eval { attr_accessor :table_name }
base.table_name = base_table_name
table_columns = DB.execute("PRAGMA table_info(#{base_table_name})")
table_columns.each do |column|
column_name = column[1].gsub(/\s/, '_')
define_method(column_name) do
instance_variable_get("@#{column_name}")
end
define_method("#{column_name}=") do |value|
instance_variable_set("@#{column_name}", value)
end
end
end
def initialize(attributes = {})
attributes.each { |key, value| send("#{key}=", value) }
end
def self.all
DB.execute("SELECT * FROM #{table_name}").map { |row| new(row) }
end
def self.find(id)
row = DB.execute("SELECT * FROM #{table_name} WHERE id = ? LIMIT 1", id).first
return unless row
new(row)
end
def save
new? ? create : update
end
def destroy
DB.execute("DELETE FROM #{table_name} WHERE id = ?", @id)
end
def new?
@id.nil?
end
def table_name
self.class.table_name
end
# Returns an array with all the field names except id
def field_names
names = instance_variables.map { |var| var.to_s.sub('@', '') }
names.delete('id')
names
end
def fields_string
"(#{field_names.join(', ')})"
end
def values_string
value_count = instance_variables.size
placeholders = Array.new(3) { '?' }
"VALUES (#{placeholders.join(', ')})"
end
def update_string
string = field_names.map { |field| "#{field} = ?" }
"#{string.join(', ')} WHERE id = ?"
end
def all_values
field_names.map { |field| send(field) }
end
def create
DB.execute("INSERT INTO #{table_name} #{fields_string} #{values_string}", *all_values)
@id = DB.last_insert_row_id
self
end
def update
DB.execute("UPDATE #{table_name} SET #{update_string}", *all_values, id)
self
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment