Class: ActiveRecord::Base

Inherits:
Object
  • Object
show all
Defined in:
lib/active_record/connection_adapters/abstract/connection_specification.rb,
lib/active_record/locking.rb,
lib/active_record/timestamp.rb,
lib/active_record/query_cache.rb,
lib/active_record/deprecated_finders.rb,
lib/active_record/connection_adapters/mysql_adapter.rb,
lib/active_record/connection_adapters/sqlite_adapter.rb,
lib/active_record/connection_adapters/sqlserver_adapter.rb,
lib/active_record/connection_adapters/postgresql_adapter.rb

Overview

The root class of all active record objects.

Defined Under Namespace

Classes: ConnectionSpecification

Constant Summary collapse

@@lock_optimistically =
true
@@record_timestamps =

Records the creation date and possibly time in created_on (date only) or created_at (date and time) and the update date and possibly time in updated_on and updated_at. This only happens if the object responds to either of these messages, which they will do automatically if the table has columns of either of these names. This feature is turned on by default.

true
@@timestamps_gmt =

deprecated: use ActiveRecord::Base.default_timezone instead.

false
@@defined_connections =

The class -> [adapter_method, config] map

{}

Class Method Summary collapse

Instance Method Summary collapse

Class Method Details

.active_connectionsObject

:nodoc:



64
65
66
67
68
69
70
# File 'lib/active_record/connection_adapters/abstract/connection_specification.rb', line 64

def self.active_connections #:nodoc:
  if allow_concurrency
    Thread.current['active_connections'] ||= {}
  else
    @@active_connections ||= {}
  end
end

.connected?Boolean

Returns true if a connection that’s accessible to this class have already been opened.

Returns:

  • (Boolean)


92
93
94
95
96
97
98
99
100
101
102
# File 'lib/active_record/connection_adapters/abstract/connection_specification.rb', line 92

def self.connected?
  klass = self
  until klass == ActiveRecord::Base.superclass
    if active_connections[klass]
      return true
    else
      klass = klass.superclass
    end
  end
  return false
end

.connection=(spec) ⇒ Object

Set the connection for the class.



116
117
118
119
120
121
# File 'lib/active_record/connection_adapters/abstract/connection_specification.rb', line 116

def connection=(spec)
  if spec.is_a?(ConnectionSpecification) and spec.config[:query_cache]
    spec = QueryCache.new(self.send(spec.adapter_method, spec.config))
  end
  self.connection_without_query_cache = spec
end

.connection_without_query_cache=Object



48
# File 'lib/active_record/query_cache.rb', line 48

alias_method :connection_without_query_cache=, :connection=

.establish_connection(spec = nil) ⇒ Object

Establishes the connection to the database. Accepts a hash as input where the :adapter key must be specified with the name of a database adapter (in lower-case) example for regular databases (MySQL, Postgresql, etc):

ActiveRecord::Base.establish_connection(
  :adapter  => "mysql",
  :host     => "localhost",
  :username => "myuser",
  :password => "mypass",
  :database => "somedatabase"
)

Example for SQLite database:

ActiveRecord::Base.establish_connection(
  :adapter => "sqlite",
  :dbfile  => "path/to/dbfile"
)

Also accepts keys as strings (for parsing from yaml for example):

ActiveRecord::Base.establish_connection(
  "adapter" => "sqlite",
  "dbfile"  => "path/to/dbfile"
)

The exceptions AdapterNotSpecified, AdapterNotFound and ArgumentError may be returned on an error.



41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
# File 'lib/active_record/connection_adapters/abstract/connection_specification.rb', line 41

def self.establish_connection(spec = nil)
  case spec
    when nil
      raise AdapterNotSpecified unless defined? RAILS_ENV
      establish_connection(RAILS_ENV)
    when ConnectionSpecification
      @@defined_connections[self] = spec
    when Symbol, String
      if configuration = configurations[spec.to_s]
        establish_connection(configuration)
      else
        raise AdapterNotSpecified, "#{spec} database is not configured"
      end
    else
      spec = spec.symbolize_keys
      unless spec.key?(:adapter) then raise AdapterNotSpecified, "database configuration does not specify adapter" end
      adapter_method = "#{spec[:adapter]}_connection"
      unless respond_to?(adapter_method) then raise AdapterNotFound, "database configuration specifies nonexistent #{spec[:adapter]} adapter" end
      remove_connection
      establish_connection(ConnectionSpecification.new(spec, adapter_method))
  end
end

.find_all(conditions = nil, orderings = nil, limit = nil, joins = nil) ⇒ Object

This method is deprecated in favor of find(:all, options).

Returns an array of all the objects that could be instantiated from the associated table in the database. The conditions can be used to narrow the selection of objects (WHERE-part), such as by “color = ‘red’”, and arrangement of the selection can be done through orderings (ORDER BY-part), such as by “last_name, first_name DESC”. A maximum of returned objects and their offset can be specified in limit with either just a single integer as the limit or as an array with the first element as the limit, the second as the offset. Examples:

Project.find_all "category = 'accounts'", "last_accessed DESC", 15
Project.find_all ["category = ?", category_name], "created ASC", [15, 20]


35
36
37
38
# File 'lib/active_record/deprecated_finders.rb', line 35

def find_all(conditions = nil, orderings = nil, limit = nil, joins = nil) # :nodoc:
  limit, offset = limit.is_a?(Array) ? limit : [ limit, nil ]
  find(:all, :conditions => conditions, :order => orderings, :joins => joins, :limit => limit, :offset => offset)
end

.find_first(conditions = nil, orderings = nil, joins = nil) ⇒ Object

This method is deprecated in favor of find(:first, options).

Returns the object for the first record responding to the conditions in conditions, such as “group = ‘master’”. If more than one record is returned from the query, it’s the first that’ll be used to create the object. In such cases, it might be beneficial to also specify orderings, like “income DESC, name”, to control exactly which record is to be used. Example:

Employee.find_first "income > 50000", "income DESC, name"


21
22
23
# File 'lib/active_record/deprecated_finders.rb', line 21

def find_first(conditions = nil, orderings = nil, joins = nil) # :nodoc:
  find(:first, :conditions => conditions, :order => orderings, :joins => joins)
end

.find_on_conditions(ids, conditions) ⇒ Object

This method is deprecated in favor of find with the :conditions option.

Works like find, but the record matching id must also meet the conditions. RecordNotFound is raised if no record can be found matching the id or meeting the condition. Example:

Person.find_on_conditions 5, "first_name LIKE '%dav%' AND last_name = 'heinemeier'"


10
11
12
# File 'lib/active_record/deprecated_finders.rb', line 10

def find_on_conditions(ids, conditions) # :nodoc:
  find(ids, :conditions => conditions)
end

.mysql_connection(config) ⇒ Object

Establishes a connection to the database that’s used by all Active Record objects.



6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
# File 'lib/active_record/connection_adapters/mysql_adapter.rb', line 6

def self.mysql_connection(config) # :nodoc:
  # Only include the MySQL driver if one hasn't already been loaded
  unless self.class.const_defined?(:Mysql)
    begin
      require_library_or_gem 'mysql'
      # The C version of mysql returns null fields in each_hash if Mysql::VERSION is defined
      ConnectionAdapters::MysqlAdapter.null_values_in_each_hash = Mysql.const_defined?(:VERSION)
    rescue LoadError => cannot_require_mysql
      # Only use the supplied backup Ruby/MySQL driver if no driver is already in place
      begin
        require 'active_record/vendor/mysql'
        require 'active_record/vendor/mysql411'
        # The ruby version of mysql returns null fields in each_hash
        ConnectionAdapters::MysqlAdapter.null_values_in_each_hash = true
      rescue LoadError
        raise cannot_require_mysql
      end
    end
  end
  

  config = config.symbolize_keys
  host     = config[:host]
  port     = config[:port]
  socket   = config[:socket]
  username = config[:username] ? config[:username].to_s : 'root'
  password = config[:password].to_s

  if config.has_key?(:database)
    database = config[:database]
  else
    raise ArgumentError, "No database specified. Missing argument: database."
  end

  mysql = Mysql.init
  mysql.ssl_set(config[:sslkey], config[:sslcert], config[:sslca], config[:sslcapath], config[:sslcipher]) if config[:sslkey]
  ConnectionAdapters::MysqlAdapter.new(mysql.real_connect(host, username, password, database, port, socket), logger, [host, username, password, database, port, socket])
end

.postgresql_connection(config) ⇒ Object

Establishes a connection to the database that’s used by all Active Record objects



6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
# File 'lib/active_record/connection_adapters/postgresql_adapter.rb', line 6

def self.postgresql_connection(config) # :nodoc:
  require_library_or_gem 'postgres' unless self.class.const_defined?(:PGconn)

  config = config.symbolize_keys
  host     = config[:host]
  port     = config[:port]     || 5432 unless host.nil?
  username = config[:username].to_s
  password = config[:password].to_s

  encoding = config[:encoding]
  min_messages = config[:min_messages]

  if config.has_key?(:database)
    database = config[:database]
  else
    raise ArgumentError, "No database specified. Missing argument: database."
  end

  pga = ConnectionAdapters::PostgreSQLAdapter.new(
    PGconn.connect(host, port, "", "", database, username, password), logger
  )

  pga.schema_search_path = config[:schema_search_path] || config[:schema_order]
  pga.execute("SET client_encoding TO '#{encoding}'") if encoding
  pga.execute("SET client_min_messages TO '#{min_messages}'") if min_messages

  pga
end

.remove_connection(klass = self) ⇒ Object

Remove the connection for this class. This will close the active connection and the defined connection (if they exist). The result can be used as argument for establish_connection, for easy re-establishing of the connection.



108
109
110
111
112
113
# File 'lib/active_record/connection_adapters/abstract/connection_specification.rb', line 108

def self.remove_connection(klass=self)
  conn = @@defined_connections[klass]
  @@defined_connections.delete(klass)
  active_connections[klass] = nil
  conn.config if conn
end

.retrieve_connectionObject

Locate the connection of the nearest super class. This can be an active or defined connections: if it is the latter, it will be opened and set as the active connection for the class it was defined for (not necessarily the current class).

Raises:

  • (ConnectionNotEstablished)


76
77
78
79
80
81
82
83
84
85
86
87
88
89
# File 'lib/active_record/connection_adapters/abstract/connection_specification.rb', line 76

def self.retrieve_connection #:nodoc:
  klass = self
  ar_super = ActiveRecord::Base.superclass
  until klass == ar_super
    if conn = active_connections[klass]
      return conn
    elsif conn = @@defined_connections[klass]
      klass.connection = conn
      return self.connection
    end
    klass = klass.superclass
  end
  raise ConnectionNotEstablished
end

.sqlite3_connection(config) ⇒ Object

sqlite3 adapter reuses sqlite_connection.



10
11
12
13
14
15
16
17
18
19
20
21
22
23
# File 'lib/active_record/connection_adapters/sqlite_adapter.rb', line 10

def sqlite3_connection(config) # :nodoc:
  parse_config!(config)

  unless self.class.const_defined?(:SQLite3)
    require_library_or_gem(config[:adapter])
  end

  db = SQLite3::Database.new(
    config[:dbfile],
    :results_as_hash => true,
    :type_translation => false
  )
  ConnectionAdapters::SQLiteAdapter.new(db, logger)
end

.sqlite_connection(config) ⇒ Object

Establishes a connection to the database that’s used by all Active Record objects



26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
# File 'lib/active_record/connection_adapters/sqlite_adapter.rb', line 26

def sqlite_connection(config) # :nodoc:
  parse_config!(config)

  unless self.class.const_defined?(:SQLite)
    require_library_or_gem(config[:adapter])

    db = SQLite::Database.new(config[:dbfile], 0)
    db.show_datatypes   = "ON" if !defined? SQLite::Version
    db.results_as_hash  = true if defined? SQLite::Version
    db.type_translation = false

    # "Downgrade" deprecated sqlite API
    if SQLite.const_defined?(:Version)
      ConnectionAdapters::SQLiteAdapter.new(db, logger)
    else
      ConnectionAdapters::DeprecatedSQLiteAdapter.new(db, logger)
    end
  end
end

.sqlserver_connection(config) ⇒ Object

:nodoc:



16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
# File 'lib/active_record/connection_adapters/sqlserver_adapter.rb', line 16

def self.sqlserver_connection(config) #:nodoc:
  require_library_or_gem 'dbi' unless self.class.const_defined?(:DBI)
  
  config = config.symbolize_keys

  mode        = config[:mode] ? config[:mode].to_s.upcase : 'ADO'
  username    = config[:username] ? config[:username].to_s : 'sa'
  password    = config[:password] ? config[:password].to_s : ''
  if mode == "ODBC"
    raise ArgumentError, "Missing DSN. Argument ':dsn' must be set in order for this adapter to work." unless config.has_key?(:dsn)
    dsn       = config[:dsn]
    conn      = DBI.connect("DBI:ODBC:#{dsn}", username, password)
  else
    raise ArgumentError, "Missing Database. Argument ':database' must be set in order for this adapter to work." unless config.has_key?(:database)
    database  = config[:database]
    host      = config[:host] ? config[:host].to_s : 'localhost'
    conn      = DBI.connect("DBI:ADO:Provider=SQLOLEDB;Data Source=#{host};Initial Catalog=#{database};User Id=#{username};Password=#{password};")
  end

  conn["AutoCommit"] = true
  ConnectionAdapters::SQLServerAdapter.new(conn, logger)
end

.timestamps_gmtObject

:nodoc:



57
58
59
60
# File 'lib/active_record/timestamp.rb', line 57

def self.timestamps_gmt #:nodoc:
  warn "timestamps_gmt is deprecated. use default_timezone instead"
  self.default_timezone == :utc
end

.timestamps_gmt=(gmt) ⇒ Object

:nodoc:



52
53
54
55
# File 'lib/active_record/timestamp.rb', line 52

def self.timestamps_gmt=( gmt ) #:nodoc:
  warn "timestamps_gmt= is deprecated. use default_timezone= instead"
  self.default_timezone = ( gmt ? :utc : :local )
end

Instance Method Details

#locking_enabled?Boolean

:nodoc:

Returns:

  • (Boolean)


54
55
56
# File 'lib/active_record/locking.rb', line 54

def locking_enabled? #:nodoc:
  lock_optimistically && respond_to?(:lock_version)
end