Created
February 12, 2020 20:02
-
-
Save rodloboz/6b918f977291f90f8c53b011bdc9f3c1 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| class Record | |
| def initialize(attributes) | |
| initialize_accessors | |
| assign_attributes(attributes) | |
| end | |
| def self.attr_accessor(*vars) | |
| @attributes ||= [] | |
| @attributes.concat vars | |
| super(*vars) | |
| end | |
| # Class Methods: | |
| class << self | |
| attr_reader :attributes | |
| def create(attributes = {}) | |
| new(attributes).save | |
| end | |
| # Read | |
| def find(id) | |
| result = DB.execute("SELECT * FROM #{table_name} WHERE id = ?", id).first | |
| result.nil? ? nil : build_record(result) | |
| end | |
| def all | |
| rows = DB.execute("SELECT * FROM #{table_name}") | |
| return [] if rows.empty? | |
| rows.map { |row| build_record(row) } | |
| end | |
| def last | |
| all.last | |
| end | |
| def first | |
| all.first | |
| end | |
| private | |
| def build_record(row) | |
| new(row.transform_keys!(&:to_sym)) | |
| end | |
| def table_columns | |
| DB.execute("PRAGMA table_info(#{table_name})").map { |a| a[1].to_sym } | |
| end | |
| def table_name | |
| to_s.gsub(/([a-z\d])([A-Z])/, '\1_\2').downcase + 's' | |
| end | |
| end | |
| def attributes | |
| self.class.attributes | |
| end | |
| def update(attributes = {}) | |
| attributes.delete(:id) | |
| assign_attributes(attributes) | |
| save | |
| end | |
| # Saves the attributes to the DB table | |
| # Called on #create and #update | |
| def save | |
| if @id.nil? | |
| # 1. Create | |
| DB.execute(build_insert_query) | |
| @id = DB.last_insert_row_id | |
| else | |
| # 2. Update | |
| DB.execute(build_update_query, *row_values) | |
| end | |
| end | |
| # Destroy | |
| def destroy | |
| DB.execute("DELETE FROM #{table_name} WHERE id = ?", @id) | |
| nil | |
| end | |
| # Assigns the values in the attributes hash | |
| # into instance variable with the respective attributes key | |
| # on #new, #create, #save, and #update | |
| def assign_attributes(attributes) | |
| attributes.each do |key, value| | |
| instance_variable_set("@#{key}", value) | |
| end | |
| end | |
| private | |
| def build_insert_query | |
| "INSERT INTO #{table_name} (#{row_headers.join(',')}) "\ | |
| "VALUES (#{row_values.map { |v| cast(v) }.join(',')})" | |
| end | |
| def build_update_query | |
| "UPDATE #{table_name} SET #{update_statement} WHERE id = #{@id}" | |
| end | |
| # Creates an attr_accessor for each table column | |
| # | |
| # Given a Posts table with :id, :title and :content, | |
| # it creates attr_accessor :id, :title, :content | |
| def initialize_accessors | |
| self.class.__send__(:attr_accessor, *self.class.__send__(:table_columns)) | |
| # self.class.table_columns.each { |c| self.class.__send__(:attr_accessor, c) } | |
| end | |
| def row_headers | |
| attributes.reject { |attr| attr == :id }.uniq | |
| end | |
| def row_values | |
| row_headers.map { |attr| send(attr) } | |
| end | |
| def update_statement | |
| row_headers.map { |attr| "#{attr} = ?" }.join(',') | |
| end | |
| def table_name | |
| self.class.__send__(:table_name) | |
| end | |
| def cast(value) | |
| case value.class.to_s | |
| when "String" then "'#{value}'" | |
| when "TrueClass" then "1" | |
| when "FalseClass" then "2" | |
| when "NilClass" then"NULL" | |
| else | |
| value.to_s | |
| end | |
| end | |
| end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment