Class: ActiveRow
- Inherits:
-
Object
- Object
- ActiveRow
- Defined in:
- lib/active_row.rb
Constant Summary collapse
- CONVERTERS =
:all
Class Method Summary collapse
-
.create(attr_hash) ⇒ Object
Accepts a hash.
-
.find(id = nil) ⇒ Object
Accepts a value for the id field.
-
.find_by(attr_hash) ⇒ Object
Accepts a hash.
- .table_directory ⇒ Object
- .table_name ⇒ Object
- .table_path ⇒ Object
Instance Method Summary collapse
-
#attributes ⇒ Object
Returns a hash of the receiving’s instance variables.
- #attributes=(new_attributes) ⇒ Object
- #destroy ⇒ Object
-
#save ⇒ Object
Returns true if the row is successfully saved.
-
#update(attr_hash) ⇒ Object
Accepts a hash.
Class Method Details
.create(attr_hash) ⇒ Object
Accepts a hash. By convention, keys should be the names of attributes as defined in the CSV headers and the atrributes of the subclass. However, attributes names are not validated by this method.
Returns self if a row is successfully created.
60 61 62 63 64 65 66 |
# File 'lib/active_row.rb', line 60 def self.create(attr_hash) CSV.open(table_path, 'a+') do |csv| # a+ => append to document # concatenate an array of values [1, 'text', 'username'] csv << CSV::Row.new(attr_hash.keys, attr_hash.values).fields end self.new(attr_hash) end |
.find(id = nil) ⇒ Object
Accepts a value for the id field.
Returns self if a row is found and returns nil if no row is found
25 26 27 28 29 |
# File 'lib/active_row.rb', line 25 def self.find(id = nil) csv_table = CSV.table(table_path, converters: CONVERTERS) csv_row = csv_table.find { |row| row.field(:id) == id } csv_row ? self.new(csv_row.to_hash) : nil end |
.find_by(attr_hash) ⇒ Object
Accepts a hash. By convention, keys should be the names of attributes as defined in the CSV headers and the atrributes of the subclass. However, attributes names are not validated by this method.
Returns self if a row is found and returns nil if no row is found.
36 37 38 39 40 41 42 |
# File 'lib/active_row.rb', line 36 def self.find_by(attr_hash) csv_table = CSV.table(table_path, converters: CONVERTERS) # Find the row where values in the CSV::Row are # equal to the values of the attributes that were provided csv_row = csv_table.find { |row| row.values_at(*attr_hash.keys) == attr_hash.values} csv_row ? self.new(csv_row.to_hash) : nil end |
.table_directory ⇒ Object
14 15 16 |
# File 'lib/active_row.rb', line 14 def self.table_directory "./tables/" end |
.table_name ⇒ Object
10 11 12 |
# File 'lib/active_row.rb', line 10 def self.table_name "#{self.name.downcase}s" end |
.table_path ⇒ Object
18 19 20 |
# File 'lib/active_row.rb', line 18 def self.table_path "#{self.table_directory}#{self.table_name}.csv" end |
Instance Method Details
#attributes ⇒ Object
Returns a hash of the receiving’s instance variables.
126 127 128 129 130 131 132 133 |
# File 'lib/active_row.rb', line 126 def attributes attrs = {} instance_variables.each { |instance_variable| # Convert the instariable to a string, removing the @ (instance notation), and convert back to a symbol attrs[instance_variable.to_s[1..-1].to_sym] = instance_variable_get(instance_variable) } attrs end |
#attributes=(new_attributes) ⇒ Object
135 136 137 138 |
# File 'lib/active_row.rb', line 135 def attributes=(new_attributes) new_attributes.each { |key, value| instance_variable_set(key, value) } attributes end |
#destroy ⇒ Object
98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 |
# File 'lib/active_row.rb', line 98 def destroy csv_table = CSV.table(table_path, converters: CONVERTERS) # Delete the row from the table if it is equivalent to the receiving instance. csv_table.delete_if do |row| row == CSV::Row.new(attributes.keys, attributes.values) end # Write the csv_table to a file, replacing the original File.open(table_path, 'w') do |f| # w => write-only f.write(csv_table.to_csv) end # Get the file's contents and close it file = File.open(table_path, 'rb') contents = file.read file.close # If all rows but the header have been deleted... if contents.lines.count < 2 # then ensure the headers are still there. File.open(table_path, 'w') do |f| # w => write-only f.write(attributes.keys.map(&:to_s).join(',')) end end self.freeze end |
#save ⇒ Object
Returns true if the row is successfully saved. (Otherwise, an error will have occurred).
45 46 47 48 49 50 51 52 53 |
# File 'lib/active_row.rb', line 45 def save attr_hash = self.attributes if self.class.find_by(attr_hash) return false else self.class.create(attr_hash) return true end end |
#update(attr_hash) ⇒ Object
Accepts a hash. By convention, keys should be the names of attributes as defined in the CSV headers and the atrributes of the subclass. However, attributes names are not validated by this method.
Returns new_row as an instance of the subclass, or returns false.
73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 |
# File 'lib/active_row.rb', line 73 def update(attr_hash) # Prevent update of id field attr_hash.reject! { |k, v| k == :id || k == "id" } csv_table = CSV.table(table_path, converters: CONVERTERS) old_row = csv_table.find { |row| row.field(:id) == id } new_row = CSV::Row.new(old_row.headers, old_row.fields) # Assign new values to the row by param name (which should be a field name) attr_hash.each { |k, v| new_row[k] = v } # Delete the old_row csv_table = CSV.table(table_path, converters: CONVERTERS) csv_table.delete_if do |row| row == old_row end csv_table << new_row # Write the csv_table to a file, replacing the original File.open(table_path, 'w') do |f| # w => write-only f.write(csv_table.to_csv) end # Note: AR returns true if successful, false if not. # If AR is successful, it updates the receiving instance's attributes. # This returns a new instance with the variables on success. new_row ? self.class.new(new_row.to_hash) : false end |