Class: LazyRecord
- Inherits:
-
Studio54::Base
- Object
- Studio54::Base
- LazyRecord
- Extended by:
- ActiveModel::Callbacks, ActiveModel::Naming, ActiveModel::Translation
- Includes:
- ActiveModel::Serializers::JSON, ActiveModel::Serializers::Xml, ActiveModel::Validations, Studio54
- Defined in:
- lib/lazy_record.rb
Constant Summary collapse
- RecordNotFound =
Class.new(StandardError)
- AssociationNotFound =
Class.new(StandardError)
Class Method Summary collapse
- .all ⇒ Object
- .all_attributes ⇒ Object
- .attributes ⇒ Object
- .belongs_to_attributes ⇒ Object
- .db_try ⇒ Object
-
.find(id) ⇒ Object
id is the primary key of the table, and does not need to be named ‘id’ in the table itself TODO take into account other dbms’s, this only works w/ mysql.
- .find_by(hash, options = {}) ⇒ Object
- .inherited(base) ⇒ Object
- .method_missing(method, *args, &block) ⇒ Object
- .nested_attributes ⇒ Object
-
.tbl_attr_accessor(*fields) ⇒ Object
used to keep track of all table attributes.
Instance Method Summary collapse
-
#attributes(options = {}) ⇒ Object
Have to implement Model#attributes to play nice with ActiveModel serializers.
-
#build_associated(tbl) ⇒ Object
This method uses the model instance’s class::has_many() method to determine what the join table is called.
-
#build_from_params!(params) ⇒ Object
meant for internal use.
-
#destroy(options = {}) ⇒ Object
delete the current model instance from the database.
-
#initialize(params = nil) ⇒ LazyRecord
constructor
if parameters are given, builds the model object with the attributes from the given parameters.
-
#save ⇒ Object
save current model instance into database.
-
#update_attributes(params, extra_where = {}) ⇒ Object
update the current model instance in the database.
Methods inherited from Studio54::Base
require_all_models, require_models
Constructor Details
#initialize(params = nil) ⇒ LazyRecord
if parameters are given, builds the model object with the attributes from the given parameters
24 25 26 27 28 29 |
# File 'lib/lazy_record.rb', line 24 def initialize(params=nil) unless params.nil? self.build_from_params!(params) end @errors = ActiveModel::Errors.new(self) end |
Class Method Details
.all ⇒ Object
334 335 336 337 338 339 340 341 |
# File 'lib/lazy_record.rb', line 334 def self.all sql = "SELECT * FROM #{self.table_name}" res = nil db_try do res = Db.conn.execute(sql) end build_from res, :always_return_array => true end |
.all_attributes ⇒ Object
43 44 45 46 47 48 |
# File 'lib/lazy_record.rb', line 43 def self.all_attributes @all_attributes ||= begin attrs = @attributes.dup attrs.unshift primary_key end end |
.attributes ⇒ Object
39 40 41 |
# File 'lib/lazy_record.rb', line 39 def self.attributes @attributes ||= [] end |
.belongs_to_attributes ⇒ Object
54 55 56 |
# File 'lib/lazy_record.rb', line 54 def self.belongs_to_attributes @belongs_to_attributes ||= [] end |
.db_try ⇒ Object
283 284 285 286 287 288 289 290 291 292 293 294 295 |
# File 'lib/lazy_record.rb', line 283 def self.db_try begin yield rescue DBI::DatabaseError @retries ||= 0; @retries += 1 if @retries == 1 load 'config/db_connect.rb' retry else raise end end end |
.find(id) ⇒ Object
id is the primary key of the table, and does not need to be named ‘id’ in the table itself TODO take into account other dbms’s, this only works w/ mysql
301 302 303 304 305 306 307 308 |
# File 'lib/lazy_record.rb', line 301 def self.find(id) sql = "SELECT * FROM #{self.table_name} WHERE #{self.primary_key} = ?" res = nil db_try do res = Db.conn.execute sql, id end build_from res end |
.find_by(hash, options = {}) ⇒ Object
310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 |
# File 'lib/lazy_record.rb', line 310 def self.find_by(hash, ={}) opts = {:conjunction => 'AND'}.merge conj = opts[:conjunction] sql = "SELECT * FROM #{self.table_name} WHERE " values = [] hash.each do |k, v| sql += "#{k} = ? #{conj} " values << v end case conj when 'AND' sql = sql[0...-4] when 'OR' sql = sql[0...-3] else raise "conjunction in sql condition (WHERE) must be one of AND, OR" end res = nil db_try do res = Db.conn.execute sql, *values end build_from res end |
.inherited(base) ⇒ Object
14 15 16 17 18 19 |
# File 'lib/lazy_record.rb', line 14 def self.inherited(base) base.class_eval do cattr_accessor :primary_key attr_reader :errors end end |
.method_missing(method, *args, &block) ⇒ Object
371 372 373 374 375 376 377 378 379 380 381 382 |
# File 'lib/lazy_record.rb', line 371 def method_missing(method, *args, &block) if method =~ %r{find_by_(.*)} h_args = {$1 => args[0]} return __send__ :find_by, h_args, &block end if method =~ %r{table_name} return __send__ :assoc_table_name= end super end |
.nested_attributes ⇒ Object
50 51 52 |
# File 'lib/lazy_record.rb', line 50 def self.nested_attributes @nested_attributes ||= [] end |
.tbl_attr_accessor(*fields) ⇒ Object
used to keep track of all table attributes
32 33 34 35 36 37 |
# File 'lib/lazy_record.rb', line 32 def self.tbl_attr_accessor *fields fields.each do |f| self.attributes << f.to_s unless self.attributes.include? f.to_s end self.__send__ :attr_accessor, *fields end |
Instance Method Details
#attributes(options = {}) ⇒ Object
Have to implement Model#attributes to play nice with ActiveModel serializers
156 157 158 159 160 161 162 163 164 165 166 167 168 |
# File 'lib/lazy_record.rb', line 156 def attributes(={}) opts = {:include_pk => true}.merge if opts[:include_pk] attrs = self.class.all_attributes else attrs = self.class.attributes end {}.tap do |h| attrs.each do |a_name| h[a_name] = instance_variable_get "@#{a_name}" end end end |
#build_associated(tbl) ⇒ Object
This method uses the model instance’s class::has_many() method to determine what the join table is called. The default join table name that this method uses if no options were given to Model::has_many() (see Model::has_many() for the passable options) is the following:
the tbl argument (for example, :tags), concatenated with ‘self`’s class’s table name (for example, ‘articles’) to make ‘tags_articles’
The default foreign key uses a similar heuristic. For the example above, it would be ‘tag_id’, because the given table name is ‘tags’, and the singular is ‘tag’. This is then concatenated with ‘_id’
To override the defaults, provide options to Model::has_many()
247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 |
# File 'lib/lazy_record.rb', line 247 def build_associated tbl self_tbl = self.class.table_name through = if _through = self.class. instance_variable_get("@join_tables")[tbl][:through] _through else "#{tbl}_#{self_tbl}" end fk = if _fk = self.class. instance_variable_get("@join_tables")[tbl][:fk] _fk else "#{tbl.to_s.singularize}_id" end tbl_model_name = tbl.to_s.singularize.camelize begin tbl_model = Object.const_get tbl_model_name rescue NameError retry if require "app/models/#{tbl_model_name.downcase}" end pk = self.class.primary_key id = __send__ pk sql = "SELECT * FROM #{tbl} INNER JOIN #{through} ON #{tbl}.#{tbl_model.primary_key} = " \ "#{through}.#{fk} WHERE #{through}.#{self_tbl.singularize + '_id'} = ?" puts sql res = nil self.class.db_try do res = Db.conn.execute sql, id end objs = tbl_model.build_from res p objs objs = Array.wrap(objs) unless Array === objs __send__("#{tbl}=", __send__(tbl) + objs) unless objs.blank? end |
#build_from_params!(params) ⇒ Object
meant for internal use
148 149 150 151 152 |
# File 'lib/lazy_record.rb', line 148 def build_from_params!(params) params.each do |k, v| self.__send__("#{k}=".intern, v) end end |
#destroy(options = {}) ⇒ Object
delete the current model instance from the database
194 195 196 197 198 199 200 201 202 203 204 205 206 |
# File 'lib/lazy_record.rb', line 194 def destroy(={}) if [:where] else sql = "DELETE FROM #{self.class.table_name} WHERE " \ "#{self.primary_key} = ?" result = nil self.class.db_try do result = Db.conn.execute sql, instance_variable_get("@#{self.primary_key}") end result end end |
#save ⇒ Object
save current model instance into database
171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 |
# File 'lib/lazy_record.rb', line 171 def save return unless valid? sql = "INSERT INTO #{self.class.table_name} (" fields = self.class.attributes sql += fields.join(', ') + ') VALUES (' fields.each {|f| sql += '?, '} sql = sql[0...-2] + ')' values = fields.map do |f| ivar = instance_variable_get "@#{f}" if ivar.nil? "NULL" else ivar end end result = nil self.class.db_try do result = Db.conn.execute sql, *values end result ? true : false end |
#update_attributes(params, extra_where = {}) ⇒ Object
update the current model instance in the database
209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 |
# File 'lib/lazy_record.rb', line 209 def update_attributes(params, extra_where={}) values = [] key = self.primary_key id = params.delete key if extra_where.blank? sql = "UPDATE #{self.class.table_name} SET " params.each do |k,v| sql += "#{k} = ?, " values << v end sql = sql[0...-2] sql += " WHERE #{key} = ?" values << id else end res = nil self.class.db_try do res = Db.conn.execute sql, *values end res end |