Class: ActiveRecord::Base

Inherits:
Object
  • Object
show all
Defined in:
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,
lib/active_record/connection_adapters/abstract/connection_specification.rb

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

{}
@@connection_cache =

The class -> thread id -> adapter cache.

Hash.new { |h, k| h[k] = Hash.new }

Class Method Summary collapse

Instance Method Summary collapse

Class Method Details

.active_connectionsObject

:nodoc:



85
86
87
88
89
90
91
# File 'lib/active_record/connection_adapters/abstract/connection_specification.rb', line 85

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

.clear_connection_cache!Object

Clears the cache which maps classes to connections.



24
25
26
# File 'lib/active_record/connection_adapters/abstract/connection_specification.rb', line 24

def self.clear_connection_cache!
  @@connection_cache.clear
end

.connected?Boolean

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

Returns:

  • (Boolean)


115
116
117
118
119
120
121
122
123
124
125
# File 'lib/active_record/connection_adapters/abstract/connection_specification.rb', line 115

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

.connectionObject

Returns the connection currently associated with the class. This can also be used to “borrow” the connection to do database work unrelated to any of the specific Active Records.



19
20
21
# File 'lib/active_record/connection_adapters/abstract/connection_specification.rb', line 19

def self.connection
  @@connection_cache[Thread.current.object_id][name] ||= retrieve_connection
end

.connection=(spec) ⇒ Object

Set the connection for the class.



141
142
143
144
145
146
# File 'lib/active_record/connection_adapters/abstract/connection_specification.rb', line 141

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",
  :database  => "path/to/dbfile"
)

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

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

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



62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
# File 'lib/active_record/connection_adapters/abstract/connection_specification.rb', line 62

def self.establish_connection(spec = nil)
  case spec
    when nil
      raise AdapterNotSpecified unless defined? RAILS_ENV
      establish_connection(RAILS_ENV)
    when ConnectionSpecification
      @@defined_connections[name] = 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

.firebird_connection(config) ⇒ Object

:nodoc:



22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
# File 'lib/active_record/connection_adapters/firebird_adapter.rb', line 22

def firebird_connection(config) # :nodoc:
  require_library_or_gem 'fireruby'
  unless defined? FireRuby::SQLType
    raise AdapterNotFound,
      'The Firebird adapter requires FireRuby version 0.4.0 or greater; you appear ' <<
      'to be running an older version -- please update FireRuby (gem install fireruby).'
  end
  config = config.symbolize_keys
  unless config.has_key?(:database)
    raise ArgumentError, "No database specified. Missing argument: database."
  end
  options = config[:charset] ? { CHARACTER_SET => config[:charset] } : {}
  connection_params = [config[:username], config[:password], options]
  db = FireRuby::Database.new_from_params(*config.values_at(:database, :host, :port, :service))
  connection = db.connect(*connection_params)
  ConnectionAdapters::FirebirdAdapter.new(connection, logger, connection_params)
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
# 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 defined? Mysql
    begin
      require_library_or_gem 'mysql'
    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'
      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, logger, [host, username, password, database, port, socket], config)
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
# 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

  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, config
  )

  pga.schema_search_path = config[:schema_search_path] || config[:schema_order]

  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.



131
132
133
134
135
136
137
138
# File 'lib/active_record/connection_adapters/abstract/connection_specification.rb', line 131

def self.remove_connection(klass=self)
  conn = @@defined_connections[klass.name]
  @@defined_connections.delete(klass.name)
  @@connection_cache[Thread.current.object_id].delete(klass.name)
  active_connections.delete(klass.name)
  @connection = 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)


97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
# File 'lib/active_record/connection_adapters/abstract/connection_specification.rb', line 97

def self.retrieve_connection #:nodoc:
  klass = self
  ar_super = ActiveRecord::Base.superclass
  until klass == ar_super
    if conn = active_connections[klass.name]
      # Reconnect if the connection is inactive.
      conn.reconnect! unless conn.active?
      return conn
    elsif conn = @@defined_connections[klass.name]
      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[:database],
    :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[:database], 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:



22
23
24
25
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/sqlserver_adapter.rb', line 22

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]
    driver_url = "DBI:ODBC:#{dsn}"
  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'
    driver_url = "DBI:ADO:Provider=SQLOLEDB;Data Source=#{host};Initial Catalog=#{database};User Id=#{username};Password=#{password};"
  end
  conn      = DBI.connect(driver_url, username, password)

  conn["AutoCommit"] = true
  ConnectionAdapters::SQLServerAdapter.new(conn, logger, [driver_url, username, password])
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

#connectionObject

Returns the connection currently associated with the class. This can also be used to “borrow” the connection to do database work that isn’t easily done without going straight to SQL.



31
32
33
# File 'lib/active_record/connection_adapters/abstract/connection_specification.rb', line 31

def connection
  self.class.connection
end

#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