module Sequel::Model::InstanceMethods

Sequel::Model instance methods that implement basic model functionality.

Attributes

_insert_values[R]

The hash of attribute values. Keys are symbols with the names of the underlying database columns. The returned hash is a reference to the receiver’s values hash, and modifying it will also modify the receiver’s values.

Artist.new(name: 'Bob').values # => {:name=>'Bob'}
Artist[1].values # => {:id=>1, :name=>'Jim', ...}
to_hash[R]

The hash of attribute values. Keys are symbols with the names of the underlying database columns. The returned hash is a reference to the receiver’s values hash, and modifying it will also modify the receiver’s values.

Artist.new(name: 'Bob').values # => {:name=>'Bob'}
Artist[1].values # => {:id=>1, :name=>'Jim', ...}
values[R]

The hash of attribute values. Keys are symbols with the names of the underlying database columns. The returned hash is a reference to the receiver’s values hash, and modifying it will also modify the receiver’s values.

Artist.new(name: 'Bob').values # => {:name=>'Bob'}
Artist[1].values # => {:id=>1, :name=>'Jim', ...}

Public Class Methods

new(values = OPTS) { |self| ... } click to toggle source

Creates new instance and passes the given values to set. If a block is given, yield the instance to the block.

Arguments:

values

should be a hash to pass to set.

Artist.new(name: 'Bob')

Artist.new do |a|
  a.name = 'Bob'
end
     # File lib/sequel/model/base.rb
1088 def initialize(values = OPTS)
1089   @values = {}
1090   @new = true
1091   @modified = true
1092   initialize_set(values)
1093   _clear_changed_columns(:initialize)
1094   yield self if defined?(yield)
1095 end

Public Instance Methods

==(obj) click to toggle source

Alias of eql?

     # File lib/sequel/model/base.rb
1125 def ==(obj)
1126   eql?(obj)
1127 end
===(obj) click to toggle source

Case equality. By default, checks equality of the primary key value, see pk_equal?.

Artist[1] === Artist[1] # => true
Artist.new === Artist.new # => false
Artist[1].set(:name=>'Bob') === Artist[1] # => true
     # File lib/sequel/model/base.rb
1135 def ===(obj)
1136   case pkv = pk
1137   when nil
1138     return false
1139   when Array
1140     return false if pkv.any?(&:nil?)
1141   end
1142 
1143   (obj.class == model) && (obj.pk == pkv)
1144 end
Also aliased as: pk_equal?
[](column) click to toggle source

Returns value of the column’s attribute.

Artist[1][:id] #=> 1
     # File lib/sequel/model/base.rb
1100 def [](column)
1101   @values[column]
1102 end
[]=(column, value) click to toggle source

Sets the value for the given column. If typecasting is enabled for this object, typecast the value based on the column’s type. If this is a new record or the typecasted value isn’t the same as the current value for the column, mark the column as changed.

a = Artist.new
a[:name] = 'Bob'
a.values #=> {:name=>'Bob'}
     # File lib/sequel/model/base.rb
1112 def []=(column, value)
1113   # If it is new, it doesn't have a value yet, so we should
1114   # definitely set the new value.
1115   # If the column isn't in @values, we can't assume it is
1116   # NULL in the database, so assume it has changed.
1117   v = typecast_value(column, value)
1118   vals = @values
1119   if new? || !vals.include?(column) || v != (c = vals[column]) || v.class != c.class
1120     change_column_value(column, v)
1121   end
1122 end
autoincrementing_primary_key() click to toggle source

The autoincrementing primary key for this model object. Should be overridden if you have a composite primary key with one part of it being autoincrementing.

     # File lib/sequel/model/base.rb
1167 def autoincrementing_primary_key
1168   primary_key
1169 end
cancel_action(msg=nil) click to toggle source

Cancel the current action. Should be called in before hooks to halt the processing of the action. If a msg argument is given and the model instance is configured to raise exceptions on failure, sets the message to use for the raised HookFailed exception.

     # File lib/sequel/model/base.rb
1175 def cancel_action(msg=nil)
1176   raise_hook_failure(msg)
1177 end
changed_columns() click to toggle source

The columns that have been updated. This isn’t completely accurate, as it could contain columns whose values have not changed.

a = Artist[1]
a.changed_columns # => []
a.name = 'Bob'
a.changed_columns # => [:name]
     # File lib/sequel/model/base.rb
1186 def changed_columns
1187   _changed_columns
1188 end
delete() click to toggle source

Deletes and returns self. Does not run destroy hooks. Look into using destroy instead.

Artist[1].delete # DELETE FROM artists WHERE (id = 1)
# => #<Artist {:id=>1, ...}>
     # File lib/sequel/model/base.rb
1195 def delete
1196   raise Sequel::Error, "can't delete frozen object" if frozen?
1197   _delete
1198   self
1199 end
destroy(opts = OPTS) click to toggle source

Like delete but runs hooks before and after delete. Uses a transaction if use_transactions is true or if the :transaction option is given and true.

Artist[1].destroy # BEGIN; DELETE FROM artists WHERE (id = 1); COMMIT;
# => #<Artist {:id=>1, ...}>
     # File lib/sequel/model/base.rb
1207 def destroy(opts = OPTS)
1208   raise Sequel::Error, "can't destroy frozen object" if frozen?
1209   checked_save_failure(opts){checked_transaction(opts){_destroy(opts)}}
1210 end
each(&block) click to toggle source

Iterates through all of the current values using each.

Album[1].each{|k, v| puts "#{k} => #{v}"}
# id => 1
# name => 'Bob'
     # File lib/sequel/model/base.rb
1217 def each(&block)
1218   @values.each(&block)
1219 end
eql?(obj) click to toggle source

Compares model instances by values.

Artist[1] == Artist[1] # => true
Artist.new == Artist.new # => true
Artist[1].set(:name=>'Bob') == Artist[1] # => false
     # File lib/sequel/model/base.rb
1226 def eql?(obj)
1227   (obj.class == model) && (obj.values == @values)
1228 end
errors() click to toggle source

Returns the validation errors associated with this object. See Errors.

     # File lib/sequel/model/base.rb
1232 def errors
1233   @errors ||= errors_class.new
1234 end
exists?() click to toggle source

Returns true when current instance exists, false otherwise. Generally an object that isn’t new will exist unless it has been deleted. Uses a database query to check for existence, unless the model object is new, in which case this is always false.

Artist[1].exists? # SELECT 1 FROM artists WHERE (id = 1)
# => true
Artist.new.exists?
# => false
     # File lib/sequel/model/base.rb
1246 def exists?
1247   new? ? false : !this.get(SQL::AliasedExpression.new(1, :one)).nil?
1248 end
extend(mod) click to toggle source

Ignore the model’s setter method cache when this instances extends a module, as the module may contain setter methods.

Calls superclass method
     # File lib/sequel/model/base.rb
1252 def extend(mod)
1253   @singleton_setter_added = true
1254   super
1255 end
freeze() click to toggle source

Freeze the object in such a way that it is still usable but not modifiable. Once an object is frozen, you cannot modify it’s values, changed_columns, errors, or dataset.

Calls superclass method
     # File lib/sequel/model/base.rb
1260 def freeze
1261   unless errors.frozen?
1262     validate
1263     errors.freeze
1264   end
1265   values.freeze
1266   _changed_columns.freeze
1267   this if !new? && model.primary_key
1268   super
1269 end
hash() click to toggle source

Value that should be unique for objects with the same class and pk (if pk is not nil), or the same class and values (if pk is nil).

Artist[1].hash == Artist[1].hash # true
Artist[1].set(name: 'Bob').hash == Artist[1].hash # true
Artist.new.hash == Artist.new.hash # true
Artist.new(name: 'Bob').hash == Artist.new.hash # false
     # File lib/sequel/model/base.rb
1278 def hash
1279   case primary_key
1280   when Array
1281     [model, !pk.all? ? @values : pk].hash
1282   when Symbol
1283     [model, pk.nil? ? @values : pk].hash
1284   else
1285     [model, @values].hash
1286   end
1287 end
id() click to toggle source

Returns value for the :id attribute, even if the primary key is not id. To get the primary key value, use pk.

Artist[1].id # => 1
     # File lib/sequel/model/base.rb
1293 def id
1294   @values[:id]
1295 end
inspect() click to toggle source

Returns a string representation of the model instance including the class name and values.

     # File lib/sequel/model/base.rb
1299 def inspect
1300   "#<#{model.name} @values=#{inspect_values}>"
1301 end
keys() click to toggle source

Returns the keys in values. May not include all column names.

Artist.new.keys # => []
Artist.new(name: 'Bob').keys # => [:name]
Artist[1].keys # => [:id, :name]
     # File lib/sequel/model/base.rb
1308 def keys
1309   @values.keys
1310 end
lock!(style=:update) click to toggle source

Refresh this record using for_update (by default, or the specified style when given) unless this is a new record. Returns self. This can be used to make sure no other process is updating the record at the same time.

If style is a string, it will be used directly. You should never pass a string to this method that is derived from user input, as that can lead to SQL injection.

A symbol may be used for database independent locking behavior, but all supported symbols have separate methods (e.g. for_update).

a = Artist[1]
Artist.db.transaction do
  a.lock!
  a.update(:name=>'A')
end

a = Artist[2]
Artist.db.transaction do
  a.lock!('FOR NO KEY UPDATE')
  a.update(:name=>'B')
end
     # File lib/sequel/model/base.rb
1335 def lock!(style=:update)
1336   _refresh(this.lock_style(style)) unless new?
1337   self
1338 end
marshallable!() click to toggle source

Remove elements of the model object that make marshalling fail. Returns self.

a = Artist[1]
a.marshallable!
Marshal.dump(a)
     # File lib/sequel/model/base.rb
1345 def marshallable!
1346   @this = nil
1347   self
1348 end
modified!(column=nil) click to toggle source

Explicitly mark the object as modified, so save_changes/update will run callbacks even if no columns have changed.

a = Artist[1]
a.save_changes # No callbacks run, as no changes
a.modified!
a.save_changes # Callbacks run, even though no changes made

If a column is given, specifically marked that column as modified, so that save_changes/update will include that column in the update. This should be used if you plan on mutating the column value instead of assigning a new column value:

a.modified!(:name)
a.name.gsub!(/[aeou]/, 'i')
     # File lib/sequel/model/base.rb
1365 def modified!(column=nil)
1366   _add_changed_column(column) if column
1367   @modified = true
1368 end
modified?(column=nil) click to toggle source

Whether this object has been modified since last saved, used by save_changes to determine whether changes should be saved. New values are always considered modified.

a = Artist[1]
a.modified? # => false
a.set(name: 'Jim')
a.modified? # => true

If a column is given, specifically check if the given column has been modified:

a.modified?(:num_albums) # => false
a.num_albums = 10
a.modified?(:num_albums) # => true
     # File lib/sequel/model/base.rb
1385 def modified?(column=nil)
1386   if column
1387     changed_columns.include?(column)
1388   else
1389     @modified || !changed_columns.empty?
1390   end
1391 end
new?() click to toggle source

Returns true if the current instance represents a new record.

Artist.new.new? # => true
Artist[1].new? # => false
     # File lib/sequel/model/base.rb
1397 def new?
1398   defined?(@new) ? @new : (@new = false)
1399 end
pk() click to toggle source

Returns the primary key value identifying the model instance. Raises an Error if this model does not have a primary key. If the model has a composite primary key, returns an array of values.

Artist[1].pk # => 1
Artist[[1, 2]].pk # => [1, 2]
     # File lib/sequel/model/base.rb
1407 def pk
1408   raise(Error, "No primary key is associated with this model") unless key = primary_key
1409   if key.is_a?(Array)
1410     vals = @values
1411     key.map{|k| vals[k]}
1412   else
1413     @values[key]
1414   end
1415 end
pk_equal?(obj)

If the receiver has a primary key value, returns true if the objects have the same class and primary key value. If the receiver’s primary key value is nil or is an array containing nil, returns false.

Artist[1].pk_equal?(Artist[1]) # => true
Artist.new.pk_equal?(Artist.new) # => false
Artist[1].set(:name=>'Bob').pk_equal?(Artist[1]) # => true
Alias for: ===
pk_hash() click to toggle source

Returns a hash mapping the receivers primary key column(s) to their values.

Artist[1].pk_hash # => {:id=>1}
Artist[[1, 2]].pk_hash # => {:id1=>1, :id2=>2}
     # File lib/sequel/model/base.rb
1421 def pk_hash
1422   model.primary_key_hash(pk)
1423 end
qualified_pk_hash(qualifier=model.table_name) click to toggle source

Returns a hash mapping the receivers qualified primary key column(s) to their values.

Artist[1].qualified_pk_hash
# => {Sequel[:artists][:id]=>1}
Artist[[1, 2]].qualified_pk_hash
# => {Sequel[:artists][:id1]=>1, Sequel[:artists][:id2]=>2}
     # File lib/sequel/model/base.rb
1431 def qualified_pk_hash(qualifier=model.table_name)
1432   model.qualified_primary_key_hash(pk, qualifier)
1433 end
refresh() click to toggle source

Reloads attributes from database and returns self. Also clears all changed_columns information. Raises an Error if the record no longer exists in the database.

a = Artist[1]
a.name = 'Jim'
a.refresh
a.name # => 'Bob'
     # File lib/sequel/model/base.rb
1443 def refresh
1444   raise Sequel::Error, "can't refresh frozen object" if frozen?
1445   _refresh(this)
1446   self
1447 end
reload() click to toggle source

Alias of refresh, but not aliased directly to make overriding in a plugin easier.

     # File lib/sequel/model/base.rb
1450 def reload
1451   refresh
1452 end
save(opts=OPTS) click to toggle source

Creates or updates the record, after making sure the record is valid and before hooks execute successfully. Fails if:

  • the record is not valid, or

  • before_save calls cancel_action, or

  • the record is new and before_create calls cancel_action, or

  • the record is not new and before_update calls cancel_action.

If save fails and either raise_on_save_failure or the :raise_on_failure option is true, it raises ValidationFailed or HookFailed. Otherwise it returns nil.

If it succeeds, it returns self.

Takes the following options:

:changed

save all changed columns, instead of all columns or the columns given

:columns

array of specific columns that should be saved.

:raise_on_failure

set to true or false to override the current raise_on_save_failure setting

:server

set the server/shard on the object before saving, and use that server/shard in any transaction.

:transaction

set to true or false to override the current use_transactions setting

:validate

set to false to skip validation

     # File lib/sequel/model/base.rb
1479 def save(opts=OPTS)
1480   raise Sequel::Error, "can't save frozen object" if frozen?
1481   set_server(opts[:server]) if opts[:server] 
1482   unless _save_valid?(opts)
1483     raise(validation_failed_error) if raise_on_failure?(opts)
1484     return
1485   end
1486   checked_save_failure(opts){checked_transaction(opts){_save(opts)}}
1487 end
save_changes(opts=OPTS) click to toggle source

Saves only changed columns if the object has been modified. If the object has not been modified, returns nil. If unable to save, returns false unless raise_on_save_failure is true.

a = Artist[1]
a.save_changes # => nil
a.name = 'Jim'
a.save_changes # UPDATE artists SET name = 'Bob' WHERE (id = 1)
# => #<Artist {:id=>1, :name=>'Jim', ...}
     # File lib/sequel/model/base.rb
1498 def save_changes(opts=OPTS)
1499   save(Hash[opts].merge!(:changed=>true)) || false if modified? 
1500 end
set(hash) click to toggle source

Updates the instance with the supplied values with support for virtual attributes, raising an exception if a value is used that doesn’t have a setter method (or ignoring it if strict_param_setting = false). Does not save the record.

artist.set(name: 'Jim')
artist.name # => 'Jim'
     # File lib/sequel/model/base.rb
1509 def set(hash)
1510   set_restricted(hash, :default)
1511 end
set_fields(hash, fields, opts=nil) click to toggle source

For each of the fields in the given array fields, call the setter method with the value of that hash entry for the field. Returns self.

You can provide an options hash, with the following options currently respected:

:missing

Can be set to :skip to skip missing entries or :raise to raise an Error for missing entries. The default behavior is not to check for missing entries, in which case the default value is used. To be friendly with most web frameworks, the missing check will also check for the string version of the argument in the hash if given a symbol.

Examples:

artist.set_fields({name: 'Jim'}, [:name])
artist.name # => 'Jim'

artist.set_fields({hometown: 'LA'}, [:name])
artist.name # => nil
artist.hometown # => 'Sac'

artist.name # => 'Jim'
artist.set_fields({}, [:name], missing: :skip)
artist.name # => 'Jim'

artist.name # => 'Jim'
artist.set_fields({}, [:name], missing: :raise)
# Sequel::Error raised
     # File lib/sequel/model/base.rb
1539 def set_fields(hash, fields, opts=nil)
1540   opts = if opts
1541     model.default_set_fields_options.merge(opts)
1542   else
1543     model.default_set_fields_options
1544   end
1545 
1546   case missing = opts[:missing]
1547   when :skip, :raise
1548     do_raise = true if missing == :raise
1549     fields.each do |f|
1550       if hash.has_key?(f) 
1551         set_column_value("#{f}=", hash[f])
1552       elsif f.is_a?(Symbol) && hash.has_key?(sf = f.to_s)
1553         set_column_value("#{sf}=", hash[sf])
1554       elsif do_raise
1555         raise(Sequel::Error, "missing field in hash: #{f.inspect} not in #{hash.inspect}")
1556       end
1557     end
1558   else
1559     fields.each{|f| set_column_value("#{f}=", hash[f])}
1560   end
1561   self
1562 end
set_server(s) click to toggle source

Set the shard that this object is tied to. Returns self.

     # File lib/sequel/model/base.rb
1565 def set_server(s)
1566   @server = s
1567   @this = @this.server(s) if @this
1568   self
1569 end
singleton_method_added(meth) click to toggle source

Clear the setter_methods cache when a method is added

Calls superclass method
     # File lib/sequel/model/base.rb
1572 def singleton_method_added(meth)
1573   @singleton_setter_added = true if meth.to_s.end_with?('=')
1574   super
1575 end
skip_validation_on_next_save!() click to toggle source

Skip all validation of the object on the next call to save, including the running of validation hooks. This is designed for and should only be used in cases where valid? is called before saving and the validate: false option cannot be passed to save.

     # File lib/sequel/model/base.rb
1582 def skip_validation_on_next_save!
1583   @skip_validation_on_next_save = true
1584 end
this() click to toggle source

Returns (naked) dataset that should return only this instance.

Artist[1].this
# SELECT * FROM artists WHERE (id = 1) LIMIT 1
     # File lib/sequel/model/base.rb
1590 def this
1591   return @this if @this
1592   raise Error, "No dataset for model #{model}" unless ds = model.instance_dataset
1593   @this = use_server(ds.where(pk_hash))
1594 end
update(hash) click to toggle source

Runs set with the passed hash and then runs save_changes.

artist.update(name: 'Jim') # UPDATE artists SET name = 'Jim' WHERE (id = 1)
     # File lib/sequel/model/base.rb
1599 def update(hash)
1600   update_restricted(hash, :default)
1601 end
update_fields(hash, fields, opts=nil) click to toggle source

Update the instance’s values by calling set_fields with the arguments, then calls save_changes.

artist.update_fields({name: 'Jim'}, [:name])
# UPDATE artists SET name = 'Jim' WHERE (id = 1)

artist.update_fields({hometown: 'LA'}, [:name])
# UPDATE artists SET name = NULL WHERE (id = 1)
     # File lib/sequel/model/base.rb
1611 def update_fields(hash, fields, opts=nil)
1612   set_fields(hash, fields, opts)
1613   save_changes
1614 end
valid?(opts = OPTS) click to toggle source

Validates the object and returns true if no errors are reported.

artist.set(name: 'Valid').valid? # => true
artist.set(name: 'Invalid').valid? # => false
artist.errors.full_messages # => ['name cannot be Invalid']
     # File lib/sequel/model/base.rb
1630 def valid?(opts = OPTS)
1631   _valid?(opts)
1632 rescue HookFailed
1633   false
1634 end
validate() click to toggle source

Validates the object. If the object is invalid, errors should be added to the errors attribute. By default, does nothing, as all models are valid by default. See the “Model Validations” guide. for details about validation. Should not be called directly by user code, call valid? instead to check if an object is valid.

     # File lib/sequel/model/base.rb
1622 def validate
1623 end

Private Instance Methods

_add_changed_column(column) click to toggle source

Add a column as a changed column.

     # File lib/sequel/model/base.rb
1639 def _add_changed_column(column)
1640   cc = _changed_columns
1641   cc << column unless cc.include?(column)
1642 end
_changed_columns() click to toggle source

Internal changed_columns method that just returns stored array.

     # File lib/sequel/model/base.rb
1645 def _changed_columns
1646   @changed_columns ||= []
1647 end
_clear_changed_columns(_reason) click to toggle source

Clear the changed columns. Reason is the reason for clearing the columns, and should be one of: :initialize, :refresh, :create or :update.

     # File lib/sequel/model/base.rb
1652 def _clear_changed_columns(_reason)
1653   _changed_columns.clear
1654 end
_delete() click to toggle source

Do the deletion of the object’s dataset, and check that the row was actually deleted.

     # File lib/sequel/model/base.rb
1658 def _delete
1659   n = _delete_without_checking
1660   raise(NoExistingObject, "Attempt to delete object did not result in a single row modification (Rows Deleted: #{n}, SQL: #{_delete_dataset.delete_sql})") if require_modification && n != 1
1661   n
1662 end
_delete_dataset() click to toggle source

The dataset to use when deleting the object. The same as the object’s dataset by default.

     # File lib/sequel/model/base.rb
1666 def _delete_dataset
1667   this
1668 end
_delete_without_checking() click to toggle source

Actually do the deletion of the object’s dataset. Return the number of rows modified.

     # File lib/sequel/model/base.rb
1672 def _delete_without_checking
1673   if sql = (m = model).fast_instance_delete_sql
1674     sql = sql.dup
1675     ds = use_server(m.dataset)
1676     ds.literal_append(sql, pk)
1677     ds.with_sql_delete(sql)
1678   else
1679     _delete_dataset.delete 
1680   end
1681 end
_destroy(opts) click to toggle source

Internal destroy method, separted from destroy to allow running inside a transaction

     # File lib/sequel/model/base.rb
1685 def _destroy(opts)
1686   called = false
1687   around_destroy do
1688     called = true
1689     before_destroy
1690     _destroy_delete
1691     after_destroy
1692   end
1693   raise_hook_failure(:around_destroy) unless called
1694   self
1695 end
_destroy_delete() click to toggle source

Internal delete method to call when destroying an object, separated from delete to allow you to override destroy’s version without affecting delete.

     # File lib/sequel/model/base.rb
1700 def _destroy_delete
1701   delete
1702 end
_insert() click to toggle source

Insert the record into the database, returning the primary key if the record should be refreshed from the database.

     # File lib/sequel/model/base.rb
1706 def _insert
1707   ds = _insert_dataset
1708   if _use_insert_select?(ds) && !(h = _insert_select_raw(ds)).nil?
1709     _save_set_values(h) if h
1710     nil
1711   else
1712     iid = _insert_raw(ds)
1713     # if we have a regular primary key and it's not set in @values,
1714     # we assume it's the last inserted id
1715     if (pk = autoincrementing_primary_key) && pk.is_a?(Symbol) && !(vals = @values)[pk]
1716       vals[pk] = iid
1717     end
1718     pk
1719   end
1720 end
_insert_dataset() click to toggle source

The dataset to use when inserting a new object. The same as the model’s dataset by default.

     # File lib/sequel/model/base.rb
1724 def _insert_dataset
1725   use_server(model.instance_dataset)
1726 end
_insert_raw(ds) click to toggle source

Insert into the given dataset and return the primary key created (if any).

     # File lib/sequel/model/base.rb
1729 def _insert_raw(ds)
1730   ds.insert(_insert_values)
1731 end
_insert_select_raw(ds) click to toggle source

Insert into the given dataset and return the hash of column values.

     # File lib/sequel/model/base.rb
1734 def _insert_select_raw(ds)
1735   ds.insert_select(_insert_values)
1736 end
_refresh(dataset) click to toggle source

Refresh using a particular dataset, used inside save to make sure the same server is used for reading newly inserted values from the database

     # File lib/sequel/model/base.rb
1744 def _refresh(dataset)
1745   _refresh_set_values(_refresh_get(dataset) || raise(NoExistingObject, "Record not found"))
1746   _clear_changed_columns(:refresh)
1747 end
_refresh_get(dataset) click to toggle source

Get the row of column data from the database.

     # File lib/sequel/model/base.rb
1750 def _refresh_get(dataset)
1751   if (sql = model.fast_pk_lookup_sql) && !dataset.opts[:lock]
1752     sql = sql.dup
1753     ds = use_server(dataset)
1754     ds.literal_append(sql, pk)
1755     ds.with_sql_first(sql)
1756   else
1757     dataset.first
1758   end
1759 end
_refresh_set_values(h) click to toggle source

Set the values to the given hash after refreshing.

     # File lib/sequel/model/base.rb
1762 def _refresh_set_values(h)
1763   @values = h
1764 end
_save(opts) click to toggle source

Internal version of save, split from save to allow running inside it’s own transaction.

     # File lib/sequel/model/base.rb
1768 def _save(opts)
1769   pk = nil
1770   called_save = false
1771   called_cu = false
1772   around_save do
1773     called_save = true
1774     before_save
1775 
1776     if new?
1777       around_create do
1778         called_cu = true
1779         before_create
1780         pk = _insert
1781         @this = nil
1782         @new = false
1783         @modified = false
1784         pk ? _save_refresh : _clear_changed_columns(:create)
1785         after_create
1786         true
1787       end
1788       raise_hook_failure(:around_create) unless called_cu
1789     else
1790       around_update do
1791         called_cu = true
1792         before_update
1793         columns = opts[:columns]
1794         if columns.nil?
1795           columns_updated = if opts[:changed]
1796             _save_update_changed_colums_hash
1797           else
1798             _save_update_all_columns_hash
1799           end
1800           _clear_changed_columns(:update)
1801         else # update only the specified columns
1802           columns = Array(columns)
1803           columns_updated = @values.reject{|k, v| !columns.include?(k)}
1804           _changed_columns.reject!{|c| columns.include?(c)}
1805         end
1806         _update_columns(columns_updated)
1807         @this = nil
1808         @modified = false
1809         after_update
1810         true
1811       end
1812       raise_hook_failure(:around_update) unless called_cu
1813     end
1814     after_save
1815     true
1816   end
1817   raise_hook_failure(:around_save) unless called_save
1818   self
1819 end
_save_refresh() click to toggle source

Refresh the object after saving it, used to get default values of all columns. Separated from _save so it can be overridden to avoid the refresh.

     # File lib/sequel/model/base.rb
1824 def _save_refresh
1825   _save_set_values(_refresh_get(this.server?(:default)) || raise(NoExistingObject, "Record not found"))
1826   _clear_changed_columns(:create)
1827 end
_save_set_values(h) click to toggle source

Set values to the provided hash. Called after a create, to set the full values from the database in the model instance.

     # File lib/sequel/model/base.rb
1831 def _save_set_values(h)
1832   @values = h
1833 end
_save_update_all_columns_hash() click to toggle source

Return a hash of values used when saving all columns of an existing object (i.e. not passing specific columns to save or using update/save_changes). Defaults to all of the object’s values except unmodified primary key columns, as some databases don’t like you setting primary key values even to their existing values.

     # File lib/sequel/model/base.rb
1841 def _save_update_all_columns_hash
1842   v = Hash[@values]
1843   cc = changed_columns
1844   Array(primary_key).each{|x| v.delete(x) unless cc.include?(x)}
1845   v
1846 end
_save_update_changed_colums_hash() click to toggle source

Return a hash of values used when saving changed columns of an existing object. Defaults to all of the objects current values that are recorded as modified.

     # File lib/sequel/model/base.rb
1851 def _save_update_changed_colums_hash
1852   cc = changed_columns
1853   @values.reject{|k,v| !cc.include?(k)}
1854 end
_save_valid?(opts) click to toggle source

Validate the object if validating on save. Skips validation completely (including validation hooks) if skip_validation_on_save! has been called on the object, resetting the flag so that future saves will validate.

     # File lib/sequel/model/base.rb
1860 def _save_valid?(opts)
1861   if @skip_validation_on_next_save
1862     @skip_validation_on_next_save = false
1863     return true
1864   end
1865 
1866   checked_save_failure(opts){_valid?(opts)}
1867 end
_update(columns) click to toggle source

Update this instance’s dataset with the supplied column hash, checking that only a single row was modified.

     # File lib/sequel/model/base.rb
1878 def _update(columns)
1879   n = _update_without_checking(columns)
1880   raise(NoExistingObject, "Attempt to update object did not result in a single row modification (SQL: #{_update_dataset.update_sql(columns)})") if require_modification && n != 1
1881   n
1882 end
_update_columns(columns) click to toggle source

Call _update with the given columns, if any are present. Plugins can override this method in order to update with additional columns, even when the column hash is initially empty.

     # File lib/sequel/model/base.rb
1872 def _update_columns(columns)
1873   _update(columns) unless columns.empty?
1874 end
_update_dataset() click to toggle source

The dataset to use when updating an object. The same as the object’s dataset by default.

     # File lib/sequel/model/base.rb
1886 def _update_dataset
1887   this
1888 end
_update_without_checking(columns) click to toggle source

Update this instances dataset with the supplied column hash.

     # File lib/sequel/model/base.rb
1891 def _update_without_checking(columns)
1892   _update_dataset.update(columns)
1893 end
_use_insert_select?(ds) click to toggle source

Whether to use insert_select when inserting a new row.

     # File lib/sequel/model/base.rb
1896 def _use_insert_select?(ds)
1897   (!ds.opts[:select] || ds.opts[:returning]) && ds.supports_insert_select? 
1898 end
_valid?(opts) click to toggle source

Internal validation method, running validation hooks.

     # File lib/sequel/model/base.rb
1901 def _valid?(opts)
1902   return errors.empty? if frozen?
1903   errors.clear
1904   called = false
1905   skip_validate = opts[:validate] == false
1906   around_validation do
1907     called = true
1908     before_validation
1909     validate unless skip_validate
1910     after_validation
1911   end
1912 
1913   return true if skip_validate
1914 
1915   if called
1916     errors.empty?
1917   else
1918     raise_hook_failure(:around_validation)
1919   end
1920 end
change_column_value(column, value) click to toggle source

Change the value of the column to given value, recording the change.

     # File lib/sequel/model/base.rb
1942 def change_column_value(column, value)
1943   _add_changed_column(column)
1944   @values[column] = value
1945 end
checked_save_failure(opts) { || ... } click to toggle source

If not raising on failure, check for HookFailed being raised by yielding and swallow it.

     # File lib/sequel/model/base.rb
1924 def checked_save_failure(opts)
1925   if raise_on_failure?(opts)
1926     yield
1927   else
1928     begin
1929       yield
1930     rescue HookFailed 
1931       nil
1932     end
1933   end
1934 end
checked_transaction(opts=OPTS) { || ... } click to toggle source

If transactions should be used, wrap the yield in a transaction block.

     # File lib/sequel/model/base.rb
1937 def checked_transaction(opts=OPTS)
1938   use_transaction?(opts) ? db.transaction({:server=>this_server}.merge!(opts)){yield} : yield
1939 end
errors_class() click to toggle source

Default error class used for errors.

     # File lib/sequel/model/base.rb
1948 def errors_class
1949   Errors
1950 end
hook_failed_error(msg) click to toggle source

A HookFailed exception for the given message tied to the current instance.

     # File lib/sequel/model/base.rb
1953 def hook_failed_error(msg)
1954   HookFailed.new(msg, self)
1955 end
initialize_clone(other) click to toggle source

Clone constructor – freeze internal data structures if the original’s are frozen.

Calls superclass method
     # File lib/sequel/model/base.rb
1959 def initialize_clone(other)
1960   super
1961   freeze if other.frozen?
1962   self
1963 end
initialize_copy(other) click to toggle source

Copy constructor – Duplicate internal data structures.

Calls superclass method
     # File lib/sequel/model/base.rb
1966 def initialize_copy(other)
1967   super
1968   @values = Hash[@values]
1969   @changed_columns = @changed_columns.dup if @changed_columns
1970   @errors = @errors.dup if @errors
1971   self
1972 end
initialize_set(h) click to toggle source

Set the columns with the given hash. By default, the same as set, but exists so it can be overridden. This is called only for new records, before changed_columns is cleared.

     # File lib/sequel/model/base.rb
1977 def initialize_set(h)
1978   set(h) unless h.empty?
1979 end
inspect_values() click to toggle source

Default inspection output for the values hash, overwrite to change what inspect displays.

     # File lib/sequel/model/base.rb
1982 def inspect_values
1983   @values.inspect
1984 end
raise_hook_failure(type=nil) click to toggle source

Raise an error appropriate to the hook type. May be swallowed by checked_save_failure depending on the raise_on_failure? setting.

     # File lib/sequel/model/base.rb
1996 def raise_hook_failure(type=nil)
1997   msg = case type
1998   when String
1999     type
2000   when Symbol
2001     "the #{type} hook failed"
2002   else
2003     "a hook failed"
2004   end
2005 
2006   raise hook_failed_error(msg)
2007 end
raise_on_failure?(opts) click to toggle source

Whether to raise or return false if this action fails. If the :raise_on_failure option is present in the hash, use that, otherwise, fallback to the object’s raise_on_save_failure (if set), or class’s default (if not).

     # File lib/sequel/model/base.rb
1990 def raise_on_failure?(opts)
1991   opts.fetch(:raise_on_failure, raise_on_save_failure)
1992 end
schema_type_class(column) click to toggle source

Get the ruby class or classes related to the given column’s type.

     # File lib/sequel/model/base.rb
2010 def schema_type_class(column)
2011   if (sch = db_schema[column]) && (type = sch[:type])
2012     db.schema_type_class(type)
2013   end
2014 end
set_restricted(hash, type) click to toggle source

Call setter methods based on keys in hash, with the appropriate values. Restrict which methods can be called based on the provided type.

     # File lib/sequel/model/base.rb
2018 def set_restricted(hash, type)
2019   return self if hash.empty?
2020   meths = setter_methods(type)
2021   strict = strict_param_setting
2022   hash.each do |k,v|
2023     m = "#{k}="
2024     if meths.include?(m)
2025       set_column_value(m, v)
2026     elsif strict
2027       # Avoid using respond_to? or creating symbols from user input
2028       if public_methods.map(&:to_s).include?(m)
2029         if Array(model.primary_key).map(&:to_s).member?(k.to_s) && model.restrict_primary_key?
2030           raise MassAssignmentRestriction, "#{k} is a restricted primary key"
2031         else
2032           raise MassAssignmentRestriction, "#{k} is a restricted column"
2033         end
2034       else
2035         raise MassAssignmentRestriction, "method #{m} doesn't exist"
2036       end
2037     end
2038   end
2039   self
2040 end
setter_methods(type) click to toggle source

Returns all methods that can be used for attribute assignment (those that end with =), depending on the type:

:default

Use the default methods allowed in the model class.

:all

Allow setting all setters, except those specifically restricted (such as ==).

Array

Only allow setting of columns in the given array.

     # File lib/sequel/model/base.rb
2048 def setter_methods(type)
2049   if type == :default && !@singleton_setter_added
2050     return model.setter_methods
2051   end
2052 
2053   meths = methods.map(&:to_s).select{|l| l.end_with?('=')} - RESTRICTED_SETTER_METHODS
2054   meths -= Array(primary_key).map{|x| "#{x}="} if primary_key && model.restrict_primary_key?
2055   meths
2056 end
this_server() click to toggle source

The server/shard that the model object’s dataset uses, or :default if the model object’s dataset does not have an associated shard.

     # File lib/sequel/model/base.rb
2060 def this_server
2061   if (s = @server)
2062     s
2063   elsif (t = @this)
2064     t.opts[:server] || :default
2065   else
2066     model.dataset.opts[:server] || :default
2067   end
2068 end
typecast_value(column, value) click to toggle source

Typecast the value to the column’s type if typecasting. Calls the database’s typecast_value method, so database adapters can override/augment the handling for database specific column types.

     # File lib/sequel/model/base.rb
2073 def typecast_value(column, value)
2074   return value unless typecast_on_assignment && db_schema && (col_schema = db_schema[column])
2075   value = nil if '' == value and typecast_empty_string_to_nil and col_schema[:type] and ![:string, :blob].include?(col_schema[:type])
2076   raise(InvalidValue, "nil/NULL is not allowed for the #{column} column") if raise_on_typecast_failure && value.nil? && (col_schema[:allow_null] == false)
2077   begin
2078     model.db.typecast_value(col_schema[:type], value)
2079   rescue InvalidValue
2080     raise_on_typecast_failure ? raise : value
2081   end
2082 end
update_restricted(hash, type) click to toggle source

Set the columns, filtered by the only and except arrays.

     # File lib/sequel/model/base.rb
2085 def update_restricted(hash, type)
2086   set_restricted(hash, type)
2087   save_changes
2088 end
use_server(ds) click to toggle source

Set the given dataset to use the current object’s shard.

     # File lib/sequel/model/base.rb
2091 def use_server(ds)
2092   @server ? ds.server(@server) : ds
2093 end
use_transaction?(opts = OPTS) click to toggle source

Whether to use a transaction for this action. If the :transaction option is present in the hash, use that, otherwise, fallback to the object’s default (if set), or class’s default (if not).

     # File lib/sequel/model/base.rb
2098 def use_transaction?(opts = OPTS)
2099   opts.fetch(:transaction, use_transactions)
2100 end
validation_failed_error() click to toggle source

An ValidationFailed exception instance to raise for this instance.

     # File lib/sequel/model/base.rb
2103 def validation_failed_error
2104   ValidationFailed.new(self)
2105 end