Class: BigRecord::Model

Inherits:
Object show all
Defined in:
lib/big_record/model.rb

Direct Known Subclasses

Base, Embedded

Constant Summary

ID_FIELD_SEPARATOR =

Constants for special characters in generated IDs. An ID might then look like this: ‘United_States-Hawaii-Oahu-Honolulu-b9cef848-a4e0-11dc-a7ba-0018f3137ea8’

'-'
ID_WHITE_SPACE_CHAR =
'_'
@@subclasses =
{}
@@configurations =
{}
@@table_name_prefix =
""
@@table_name_suffix =
""
@@pluralize_table_names =
true
@@colorize_logging =
true
@@default_timezone =
:local
@@generate_read_methods =
false
@@allow_concurrency =
false

Class Method Summary

Instance Method Summary

Constructor Details

- (Model) initialize(attrs = nil)

New objects can be instantiated as either empty (pass no construction parameter) or pre-set with attributes but not yet saved (pass a hash with key names matching the associated table column names). In both instances, valid attribute keys are determined by the column names of the associated table — hence you can’t have attributes that aren’t part of the table columns.

Parameters:

  • (Hash) Optional

    hash argument consisting of keys that match the names of the columns, and their values.



144
145
146
147
148
# File 'lib/big_record/model.rb', line 144

def initialize(attrs = nil)
  preinitialize(attrs)
  @attributes = attributes_from_column_definition
  self.attributes = attrs unless attrs.nil?
end

Dynamic Method Handling

This class handles dynamic methods through the method_missing method

- (Object) method_missing(method_id, *args, &block) (protected)

Allows access to the object attributes, which are held in the @attributes hash, as were they first-class methods. So a Person class with a name attribute can use Person#name and Person#name= and never directly use the attributes hash — except for multiple assigns with ActiveRecord#attributes=. A Milestone class can also ask Milestone#completed? to test that the completed attribute is not nil or 0.

It’s also possible to instantiate related objects, so a Client class belonging to the clients table with a master_id foreign key can instantiate master through Client#master.



613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
# File 'lib/big_record/model.rb', line 613

def method_missing(method_id, *args, &block)
  method_name = method_id.to_s
  if column_for_attribute(method_name) or
      ((md = /\?$/.match(method_name)) and
      column_for_attribute(query_method_name = md.pre_match) and
      method_name = query_method_name)
    define_read_methods if self.class.read_methods.empty? && self.class.generate_read_methods
    md ? query_attribute(method_name) : read_attribute(method_name)
  elsif self.class.primary_key.to_s == method_name
    id
  elsif (md = self.class.match_attribute_method?(method_name))
    attribute_name, method_type = md.pre_match, md.to_s
    if column_for_attribute(attribute_name)
      __send__("attribute#{method_type}", attribute_name, *args, &block)
    else
      super
    end
  else
    super
  end
end

Class Method Details

+ (Object) ===(object)

Overwrite the default class equality method to provide support for association proxies.



822
823
824
# File 'lib/big_record/model.rb', line 822

def ===(object)
  object.is_a?(self)
end

+ (Object) accessible_attributes

Returns an array of all the attributes that have been made accessible to mass-assignment.



1010
1011
1012
# File 'lib/big_record/model.rb', line 1010

def accessible_attributes 
  read_inheritable_attribute(:attr_accessible)
end

+ (Object) alias_attribute(alias_name, fully_qualified_name)

Define aliases to the fully qualified attributes



910
911
912
# File 'lib/big_record/model.rb', line 910

def alias_attribute(alias_name, fully_qualified_name)
  self.class_eval "def \#{alias_name}\nread_attribute(\"\#{fully_qualified_name}\")\nend\ndef \#{alias_name}=(value)\nwrite_attribute(\"\#{fully_qualified_name}\", value)\nend\n"
end

+ (Object) attr_accessible(*attributes)

Specifies a white list of model attributes that can be set via mass-assignment, such as new(attributes), update_attributes(attributes), or attributes=(attributes)

This is the opposite of the attr_protected macro: Mass-assignment will only set attributes in this list, to assign to the rest of attributes you can use direct writer methods. This is meant to protect sensitive attributes from being overwritten by malicious users tampering with URLs or forms. If you’d rather start from an all-open default and restrict attributes as needed, have a look at attr_protected.

  class Customer < ActiveRecord::Base
    attr_accessible :name, :nickname
  end

  customer = Customer.new(:name => "David", :nickname => "Dave", :credit_rating => "Excellent")
  customer.credit_rating # => nil
  customer.attributes = { :name => "Jolly fellow", :credit_rating => "Superb" }
  customer.credit_rating # => nil

  customer.credit_rating = "Average"
  customer.credit_rating # => "Average"


1005
1006
1007
# File 'lib/big_record/model.rb', line 1005

def attr_accessible(*attributes)
  write_inheritable_attribute(:attr_accessible, Set.new(attributes.map(&:to_s)) + (accessible_attributes || []))
end

+ (Object) attr_create_accessible(*attributes)

Attributes listed as create_accessible work with mass assignment ONLY on creation. After that, any updates to that attribute will be protected from mass assignment. This differs from attr_readonly since that macro prevents attributes from ever being changed (even with the explicit setters) after the record is created.

  class Customer < BigRecord::Base
    attr_create_accessible :name
  end

  customer = Customer.new(:name => "Greg")
  customer.name # => "Greg"
  customer.save # => true

  customer.attributes = { :name => "Nerd" }
  customer.name # => "Greg"
  customer.name = "Nerd"
  customer.name # => "Nerd"


1041
1042
1043
# File 'lib/big_record/model.rb', line 1041

def attr_create_accessible(*attributes)
 write_inheritable_attribute(:attr_create_accessible, Set.new(attributes.map(&:to_s)) + (create_accessible_attributes || []))
end

+ (Object) attr_protected(*attributes)

Attributes named in this macro are protected from mass-assignment, such as new(attributes), update_attributes(attributes), or attributes=(attributes).

Mass-assignment to these attributes will simply be ignored, to assign to them you can use direct writer methods. This is meant to protect sensitive attributes from being overwritten by malicious users tampering with URLs or forms.

  class Customer < ActiveRecord::Base
    attr_protected :credit_rating
  end

  customer = Customer.new("name" => David, "credit_rating" => "Excellent")
  customer.credit_rating # => nil
  customer.attributes = { "description" => "Jolly fellow", "credit_rating" => "Superb" }
  customer.credit_rating # => nil

  customer.credit_rating = "Average"
  customer.credit_rating # => "Average"

To start from an all-closed default and enable attributes as needed, have a look at attr_accessible.



972
973
974
# File 'lib/big_record/model.rb', line 972

def attr_protected(*attributes)
  write_inheritable_attribute(:attr_protected, Set.new(attributes.map {|a| a.to_s}) + (protected_attributes || []))
end

+ (Object) attr_readonly(*attributes)

Attributes listed as readonly can be set for a new record, but will be ignored in database updates afterwards.



1015
1016
1017
# File 'lib/big_record/model.rb', line 1015

def attr_readonly(*attributes)
 write_inheritable_attribute(:attr_readonly, Set.new(attributes.map(&:to_s)) + (readonly_attributes || []))
end

+ (Object) base_class

Raises:



826
827
828
# File 'lib/big_record/model.rb', line 826

def base_class
  raise NotImplemented
end

+ (Object) benchmark(title, log_level = Logger::DEBUG, use_silence = true)

Log and benchmark multiple statements in a single block.

The benchmark is only recorded if the current level of the logger matches the log_level, which makes it easy to include benchmarking statements in production software that will remain inexpensive because the benchmark will only be conducted if the log level is low enough.

The logging of the multiple statements is turned off unless use_silence is set to false.

Examples:

Project.benchmark("Creating project") do
  project = Project.create("name" => "stuff")
  project.create_manager("name" => "David")
  project.milestones << Milestone.find(:all)
end


802
803
804
805
806
807
808
809
810
811
# File 'lib/big_record/model.rb', line 802

def benchmark(title, log_level = Logger::DEBUG, use_silence = true)
  if logger && logger.level == log_level
    result = nil
    seconds = Benchmark.realtime { result = use_silence ? silence { yield } : yield }
    logger.add(log_level, "#{title} (#{'%.5f' % seconds})")
    result
  else
    yield
  end
end

+ (ConnectionAdapters::Column) column(name, type, options = {})

Macro for defining a new column for a model. Invokes create_column and adds the new column into the model’s column hash.

Parameters:

Options Hash (options):

  • (true, false) :collection N/A

    Whether this column is a collection.

  • (String) :alias N/A

    Define an alias for the column that cannot be inferred. By default, ‘attribute:name’ will be aliased to ‘name’.

  • (String) :default N/A

    Default value to set for this column.

Returns:



892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
# File 'lib/big_record/model.rb', line 892

def column(name, type, options={})
  name = name.to_s
  name = "#{self.default_column_prefix}#{name}" unless (name =~ /:/) || self.default_column_prefix.blank?

  @columns_hash = default_columns unless @columns_hash

  # The other variables that are cached and depend on @columns_hash need to be reloaded
  invalidate_columns

  c = create_column(name, type, options)
  @columns_hash[c.name] = c

  alias_attribute c.alias, c.name if c.alias

  c
end

+ (Object) column_methods_hash

Returns a hash of all the methods added to query each of the columns in the table with the name of the method as the key and true as the value. This makes it possible to do O(1) lookups in respond_to? to check if a given method for attribute is available.



872
873
874
875
876
877
878
879
880
881
# File 'lib/big_record/model.rb', line 872

def column_methods_hash 
  @dynamic_methods_hash ||= column_names.inject(Hash.new(false)) do |methods, attr|
    attr_name = attr.to_s
    methods[attr.to_sym]       = attr_name
    methods["#{attr}=".to_sym] = attr_name
    methods["#{attr}?".to_sym] = attr_name
    methods["#{attr}_before_type_cast".to_sym] = attr_name
    methods
  end
end

+ (Object) column_names

Returns an array of column names as strings.



859
860
861
# File 'lib/big_record/model.rb', line 859

def column_names
  @column_names = columns_hash.keys
end

+ (Object) columns

Override this method in the subclasses to add new columns. This is different from ActiveRecord because the number of columns in an Hbase table is variable.



832
833
834
# File 'lib/big_record/model.rb', line 832

def columns
  @columns = columns_hash.values
end

+ (Object) columns_hash

Returns a hash of column objects for the table associated with this class.



837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
# File 'lib/big_record/model.rb', line 837

def columns_hash
  unless @all_columns_hash
    # add default hbase columns
    @all_columns_hash =
      if self == base_class
        if @columns_hash
          default_columns.merge(@columns_hash)
        else
          @columns_hash = default_columns
        end
      else
        if @columns_hash
          superclass.columns_hash.merge(@columns_hash)
        else
          superclass.columns_hash
        end
      end
  end
  @all_columns_hash
end

+ (Object) content_columns

Returns an array of column objects where the primary id, all columns ending in "_id" or "_count", and columns used for single table inheritance have been removed.



865
866
867
# File 'lib/big_record/model.rb', line 865

def content_columns
  @content_columns ||= columns.reject{|c| c.primary || "id"}
end

+ (Object) create_accessible_attributes

Returns an array of all the attributes that have been specified as create_accessible.



1046
1047
1048
# File 'lib/big_record/model.rb', line 1046

def create_accessible_attributes
 read_inheritable_attribute(:attr_create_accessible)
end

+ (Object) default_column_prefix

Default column prefix used when auto-generating column attribute names



1051
1052
1053
# File 'lib/big_record/model.rb', line 1051

def default_column_prefix
  ""
end

+ (Object) human_attribute_name(attribute_key_name)

Transforms attribute key names into a more humane format, such as "First name" instead of "first_name". Example:

  Person.human_attribute_name("first_name") # => "First name"

Deprecated in favor of just calling "first_name".humanize



930
931
932
# File 'lib/big_record/model.rb', line 930

def human_attribute_name(attribute_key_name) #:nodoc:
  attribute_key_name.humanize
end

+ (Object) inherited(child)

:nodoc:



68
69
70
71
72
73
# File 'lib/big_record/model.rb', line 68

def self.inherited(child) #:nodoc:
  @@subclasses[self] ||= []
  @@subclasses[self] << child
  child.set_table_name child.name.tableize if child.superclass == BigRecord::Base
  super
end

+ (Object) instantiate(raw_record)

Finder methods must instantiate through this method.



939
940
941
942
943
944
945
946
# File 'lib/big_record/model.rb', line 939

def instantiate(raw_record)
  record = self.allocate
  record.deserialize(raw_record)
  record.preinitialize(raw_record)
  record.instance_variable_set(:@new_record, false)
  record.send("safe_attributes=", raw_record, false)
  record
end

+ (Object) primary_key

Evaluate the name of the column of the primary key only once

Raises:



784
785
786
# File 'lib/big_record/model.rb', line 784

def primary_key
  raise NotImplemented
end

+ (Object) protected_attributes

Returns an array of all the attributes that have been protected from mass-assignment.



977
978
979
# File 'lib/big_record/model.rb', line 977

def protected_attributes 
  read_inheritable_attribute(:attr_protected)
end

+ (Object) quote_value(value, c = nil)

:nodoc:



934
935
936
# File 'lib/big_record/model.rb', line 934

def quote_value(value, c = nil) #:nodoc:
  connection.quote(value,c)
end

+ (Object) read_methods

Contains the names of the generated reader methods.



923
924
925
# File 'lib/big_record/model.rb', line 923

def read_methods 
  @read_methods ||= Set.new
end

+ (Object) readonly_attributes

Returns an array of all the attributes that have been specified as readonly.



1020
1021
1022
# File 'lib/big_record/model.rb', line 1020

def readonly_attributes
 read_inheritable_attribute(:attr_readonly)
end

+ (Object) reset_subclasses

:nodoc:



75
76
77
78
79
80
81
82
83
84
85
86
87
# File 'lib/big_record/model.rb', line 75

def self.reset_subclasses 
  nonreloadables = []
  subclasses.each do |klass|
    unless Dependencies.autoloaded? klass
      nonreloadables << klass
      next
    end
    klass.instance_variables.each { |var| klass.send(:remove_instance_variable, var) }
    klass.instance_methods(false).each { |m| klass.send :undef_method, m }
  end
  @@subclasses = {}
  nonreloadables.each { |klass| (@@subclasses[klass.superclass] ||= []) << klass }
end

+ (Object) silence

Silences the logger for the duration of the block.



814
815
816
817
818
819
# File 'lib/big_record/model.rb', line 814

def silence
  old_logger_level, logger.level = logger.level, Logger::ERROR if logger
  yield
ensure
  logger.level = old_logger_level if logger
end

+ (Boolean) store_primary_key?

Returns:

  • (Boolean)


91
92
93
# File 'lib/big_record/model.rb', line 91

def self.store_primary_key?
  false
end

+ (Object) undecorated_table_name(class_name = base_class.name)

Guesses the table name, but does not decorate it with prefix and suffix information.



1093
1094
1095
1096
1097
# File 'lib/big_record/model.rb', line 1093

def undecorated_table_name(class_name = base_class.name)
  table_name = Inflector.underscore(Inflector.demodulize(class_name))
  table_name = Inflector.pluralize(table_name) if pluralize_table_names
  table_name
end

Instance Method Details

- (Object) ==(comparison_object)

Returns true if the comparison_object is the same object, or is of the same type and has the same id.



310
311
312
313
314
315
# File 'lib/big_record/model.rb', line 310

def ==(comparison_object)
  comparison_object.equal?(self) ||
    (comparison_object.instance_of?(self.class) &&
      comparison_object.id == id &&
      !comparison_object.new_record?)
end

- (Object) [](attr_name)

Returns the value of the attribute identified by attr_name after it has been typecast (for example, "2004-12-12" in a data column is cast to a date object, like Date.new(2004, 12, 12)). (Alias for the protected read_attribute method).



225
226
227
# File 'lib/big_record/model.rb', line 225

def [](attr_name)
  read_attribute(attr_name)
end

- (Object) []=(attr_name, value)

Updates the attribute identified by attr_name with the specified value. (Alias for the protected write_attribute method).



231
232
233
# File 'lib/big_record/model.rb', line 231

def []=(attr_name, value)
  write_attribute(attr_name, value)
end

- (Object) all_attributes_loaded=(loaded)



255
256
257
# File 'lib/big_record/model.rb', line 255

def all_attributes_loaded=(loaded)
  @all_attributes_loaded = loaded
end

- (Boolean) all_attributes_loaded?

Returns:

  • (Boolean)


259
260
261
# File 'lib/big_record/model.rb', line 259

def all_attributes_loaded?
  @all_attributes_loaded
end

- (Object) attribute_for_inspect(attr_name)

Format attributes nicely for inspect.



264
265
266
267
268
269
270
271
272
273
274
# File 'lib/big_record/model.rb', line 264

def attribute_for_inspect(attr_name)
  value = read_attribute(attr_name)

  if value.is_a?(String) && value.length > 50
    "#{value[0..50]}...".inspect
  elsif value.is_a?(Date) || value.is_a?(Time)
    %("#{value.to_s(:db)}")
  else
    value.inspect
  end
end

- (Object) attribute_names

Returns an array of names for the attributes available on this object sorted alphabetically.



295
296
297
# File 'lib/big_record/model.rb', line 295

def attribute_names
  @attributes.keys.sort
end

- (String, ...) attribute_present?(attribute)

Returns true if the specified attribute has been set by the user or by a database load and is neither nil nor empty? (the latter only applies to objects that respond to empty?, most notably Strings).

Returns:

  • (String, Symbol)

    Name of an attribute.

  • (true, false)

    Whether that attribute exists.



281
282
283
284
# File 'lib/big_record/model.rb', line 281

def attribute_present?(attribute)
  value = read_attribute(attribute)
  !value.blank? or value == 0
end

- (Hash) attributes

Get the attributes hash of the object.

Returns:

  • (Hash)

    a duplicated attributes hash



207
208
209
# File 'lib/big_record/model.rb', line 207

def attributes()
  @attributes.dup
end

- (Object) attributes=(new_attributes, guard_protected_attributes = true)

Allows you to set all the attributes at once by passing in a hash with keys matching the attribute names (which again matches the column names). Sensitive attributes can be protected from this form of mass-assignment by using the attr_protected macro. Or you can alternatively specify which attributes can be accessed in with the attr_accessible macro. Then all the attributes not included in that won’t be allowed to be mass-assigned.



240
241
242
243
244
245
246
247
248
249
250
251
252
253
# File 'lib/big_record/model.rb', line 240

def attributes=(new_attributes, guard_protected_attributes = true)
  return if new_attributes.nil?
  attributes = new_attributes.dup
  attributes.stringify_keys!

  multi_parameter_attributes = []
  attributes = remove_attributes_protected_from_mass_assignment(attributes) if guard_protected_attributes

  attributes.each do |k, v|
    k.include?("(") ? multi_parameter_attributes << [ k, v ] : send(k + "=", v)
  end

  assign_multiparameter_attributes(multi_parameter_attributes)
end

- (Object) column_for_attribute(name)

Overridden by FamilySpanColumns Returns the column object for the named attribute.



305
306
307
# File 'lib/big_record/model.rb', line 305

def column_for_attribute(name)
  self.class.columns_hash[name.to_s]
end

- (Object) connection

Returns the connection adapter of the current session.



413
414
415
# File 'lib/big_record/model.rb', line 413

def connection
  self.class.connection
end

- (Object) deserialize(attrs = nil)



157
158
# File 'lib/big_record/model.rb', line 157

def deserialize(attrs = nil)
end

- (Object) destroy

Deletes the record in the database and freezes this instance to reflect that no changes should be made (since they can’t be persisted).

Raises:



390
391
392
# File 'lib/big_record/model.rb', line 390

def destroy
  raise NotImplemented
end

- (Boolean) eql?(comparison_object)

Delegates to ==

Returns:

  • (Boolean)


318
319
320
# File 'lib/big_record/model.rb', line 318

def eql?(comparison_object)
  self == (comparison_object)
end

- (Object) freeze

Just freeze the attributes hash, such that associations are still accessible even on destroyed records.



350
351
352
# File 'lib/big_record/model.rb', line 350

def freeze
  @attributes.freeze; self
end

- (true, false) frozen?

Checks whether the object has had its attributes hash frozen.

Returns:

  • (true, false)


357
358
359
# File 'lib/big_record/model.rb', line 357

def frozen?
  @attributes.frozen?
end

- (String, ...) has_attribute?(attr_name)

Returns true if the given attribute is in the attributes hash

Returns:

  • (String, Symbol)

    Name of an attribute.

  • (true, false)

    Whether that attribute exists in the attributes hash.



290
291
292
# File 'lib/big_record/model.rb', line 290

def has_attribute?(attr_name)
  @attributes.has_key?(attr_name.to_s)
end

- (Object) hash

Delegates to id in order to allow two records of the same type and id to work with something like:

  [ Person.find(1), Person.find(2), Person.find(3) ] & [ Person.find(1), Person.find(4) ] # => [ Person.find(1) ]


324
325
326
# File 'lib/big_record/model.rb', line 324

def hash
  id.hash
end

- (Object) human_attribute_name(attribute_key)



299
300
301
# File 'lib/big_record/model.rb', line 299

def human_attribute_name(attribute_key)
  self.class.human_attribute_name(attribute_key)
end

- (Object) id

A model instance’s primary key is always available as model.id whether you name it the default ‘id’ or set it to something else.



190
191
192
193
194
195
# File 'lib/big_record/model.rb', line 190

def id
  attr_name = self.class.primary_key
  c = column_for_attribute(attr_name)
  define_read_method(:id, attr_name, c) if self.class.generate_read_methods
  read_attribute(attr_name)
end

- (Object) id=(value)

Sets the primary ID.



366
367
368
# File 'lib/big_record/model.rb', line 366

def id=(value)
  write_attribute(self.class.primary_key, value)
end

- (Object) inspect

Returns the contents of the record as a nicely formatted string.



428
429
430
431
432
433
434
435
# File 'lib/big_record/model.rb', line 428

def inspect
  attributes_as_nice_string = self.class.column_names.collect { |name|
    if has_attribute?(name) || new_record?
      "#{name}: #{attribute_for_inspect(name)}"
    end
  }.compact.join(", ")
  "#<#{self.class} #{attributes_as_nice_string}>"
end

- (Boolean) new_record?

Returns true if this object hasn’t been saved yet — that is, a record for the object doesn’t yet exist in the data store.

Returns:

  • (Boolean)


372
373
374
# File 'lib/big_record/model.rb', line 372

def new_record?
  false
end

- (Object) preinitialize(attrs = nil)

Callback method meant to be overriden by subclasses if they need to preload some attributes before initializing the record. (usefull when using a meta model where the list of columns depends on the value of an attribute)



153
154
155
# File 'lib/big_record/model.rb', line 153

def preinitialize(attrs = nil)
  @attributes = {}
end

- (Object) quoted_id

:nodoc:



361
362
363
# File 'lib/big_record/model.rb', line 361

def quoted_id 
  quote_value(id, column_for_attribute(self.class.primary_key))
end

- (Object) readonly!

Sets the record to be readonly



423
424
425
# File 'lib/big_record/model.rb', line 423

def readonly! 
  @readonly = true
end

- (Boolean) readonly?

Records loaded through joins with piggy-back attributes will be marked as read only as they cannot be saved and return true to this query.

Returns:

  • (Boolean)


418
419
420
# File 'lib/big_record/model.rb', line 418

def readonly?
  @readonly == true
end

- (Object) reload(options = nil)

Reloads the attributes of this object from the database. The optional options argument is passed to find when reloading so you may do e.g. record.reload(:lock => true) to reload the same record with an exclusive row lock.

Returns:

  • Itself with reloaded attributes.



217
218
219
220
# File 'lib/big_record/model.rb', line 217

def reload(options = nil)
  @attributes.update(self.class.find(self.id, options).instance_variable_get('@attributes'))
  self
end

- (Boolean) respond_to?(method, include_priv = false) Also known as: respond_to_without_attributes?

A Person object with a name attribute can ask person.respond_to?("name"), person.respond_to?("name="), and person.respond_to?("name?") which will all return true.

Returns:

  • (Boolean)


333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
# File 'lib/big_record/model.rb', line 333

def respond_to?(method, include_priv = false)
  if @attributes.nil?
    return super
  elsif attr_name = self.class.column_methods_hash[method.to_sym]
    return true if @attributes.include?(attr_name) || attr_name == self.class.primary_key
    return false if self.class.read_methods.include?(attr_name)
  elsif @attributes.include?(method.to_s)
    return true
  elsif md = self.class.match_attribute_method?(method.to_s)
    return true if @attributes.include?(md.pre_match)
  end
  # super must be called at the end of the method, because the inherited respond_to?
  # would return true for generated readers, even if the attribute wasn't present
  super
end

- (Object) safe_attributes=(new_attributes, guard_protected_attributes = true)

Safe version of attributes= so that objects can be instantiated even if columns are removed.

Parameters:



165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
# File 'lib/big_record/model.rb', line 165

def safe_attributes=(new_attributes, guard_protected_attributes = true)
  return if new_attributes.nil?
  attributes = new_attributes.dup
  attributes.stringify_keys!

  multi_parameter_attributes = []
  attributes = remove_attributes_protected_from_mass_assignment(attributes) if guard_protected_attributes

  attributes.each do |k, v|
    begin
      k.include?("(") ? multi_parameter_attributes << [ k, v ] : send(k + "=", v) if v
    rescue
      logger.debug "#{__FILE__}:#{__LINE__} Warning! Ignoring attribute '#{k}' because it doesn't exist anymore"
    end
  end

  begin
    assign_multiparameter_attributes(multi_parameter_attributes)
  rescue
    logger.debug "#{__FILE__}:#{__LINE__} Warning! Ignoring multiparameter attributes because some don't exist anymore"
  end
end

- (Object) save

  • No record exists: Creates a new record with values matching those of the object attributes.
  • A record does exist: Updates the record with values matching those of the object attributes.

Raises:



378
379
380
# File 'lib/big_record/model.rb', line 378

def save
  raise NotImplemented
end

- (Object) save!

Attempts to save the record, but instead of just returning false if it couldn’t happen, it raises a RecordNotSaved exception

Raises:



384
385
386
# File 'lib/big_record/model.rb', line 384

def save!
  raise NotImplemented
end

- (String) to_s

Default to_s method that just returns invokes the #id method

Returns:

  • (String)

    The row identifier/id of the record



200
201
202
# File 'lib/big_record/model.rb', line 200

def to_s
  id
end

- (Object) update_attribute(name, value)

Updates a single attribute and saves the record. This is especially useful for boolean flags on existing records. Note: This method is overwritten by the Validation module that’ll make sure that updates made with this method doesn’t get subjected to validation checks. Hence, attributes can be updated even if the full object isn’t valid.

Raises:



397
398
399
# File 'lib/big_record/model.rb', line 397

def update_attribute(name, value)
  raise NotImplemented
end

- (Object) update_attributes(attributes)

Updates all the attributes from the passed-in Hash and saves the record. If the object is invalid, the saving will fail and false will be returned.

Raises:



403
404
405
# File 'lib/big_record/model.rb', line 403

def update_attributes(attributes)
  raise NotImplemented
end

- (Object) update_attributes!(attributes)

Updates an object just like Base.update_attributes but calls save! instead of save so an exception is raised if the record is invalid.

Raises:



408
409
410
# File 'lib/big_record/model.rb', line 408

def update_attributes!(attributes)
  raise NotImplemented
end