PageRenderTime 63ms CodeModel.GetById 28ms RepoModel.GetById 0ms app.codeStats 0ms

/activerecord/lib/active_record/base.rb

https://github.com/ghar/rails
Ruby | 1135 lines | 390 code | 78 blank | 667 comment | 47 complexity | aa56ee58b914274dd11608552a7b9f43 MD5 | raw file
  1. begin
  2. require 'psych'
  3. rescue LoadError
  4. end
  5. require 'yaml'
  6. require 'set'
  7. require 'active_support/benchmarkable'
  8. require 'active_support/dependencies'
  9. require 'active_support/descendants_tracker'
  10. require 'active_support/time'
  11. require 'active_support/core_ext/class/attribute'
  12. require 'active_support/core_ext/class/attribute_accessors'
  13. require 'active_support/core_ext/class/delegating_attributes'
  14. require 'active_support/core_ext/class/attribute'
  15. require 'active_support/core_ext/array/extract_options'
  16. require 'active_support/core_ext/hash/deep_merge'
  17. require 'active_support/core_ext/hash/indifferent_access'
  18. require 'active_support/core_ext/hash/slice'
  19. require 'active_support/core_ext/string/behavior'
  20. require 'active_support/core_ext/kernel/singleton_class'
  21. require 'active_support/core_ext/module/delegation'
  22. require 'active_support/core_ext/module/introspection'
  23. require 'active_support/core_ext/object/duplicable'
  24. require 'active_support/core_ext/object/blank'
  25. require 'arel'
  26. require 'active_record/errors'
  27. require 'active_record/log_subscriber'
  28. module ActiveRecord #:nodoc:
  29. # = Active Record
  30. #
  31. # Active Record objects don't specify their attributes directly, but rather infer them from
  32. # the table definition with which they're linked. Adding, removing, and changing attributes
  33. # and their type is done directly in the database. Any change is instantly reflected in the
  34. # Active Record objects. The mapping that binds a given Active Record class to a certain
  35. # database table will happen automatically in most common cases, but can be overwritten for the uncommon ones.
  36. #
  37. # See the mapping rules in table_name and the full example in link:files/activerecord/README_rdoc.html for more insight.
  38. #
  39. # == Creation
  40. #
  41. # Active Records accept constructor parameters either in a hash or as a block. The hash
  42. # method is especially useful when you're receiving the data from somewhere else, like an
  43. # HTTP request. It works like this:
  44. #
  45. # user = User.new(:name => "David", :occupation => "Code Artist")
  46. # user.name # => "David"
  47. #
  48. # You can also use block initialization:
  49. #
  50. # user = User.new do |u|
  51. # u.name = "David"
  52. # u.occupation = "Code Artist"
  53. # end
  54. #
  55. # And of course you can just create a bare object and specify the attributes after the fact:
  56. #
  57. # user = User.new
  58. # user.name = "David"
  59. # user.occupation = "Code Artist"
  60. #
  61. # == Conditions
  62. #
  63. # Conditions can either be specified as a string, array, or hash representing the WHERE-part of an SQL statement.
  64. # The array form is to be used when the condition input is tainted and requires sanitization. The string form can
  65. # be used for statements that don't involve tainted data. The hash form works much like the array form, except
  66. # only equality and range is possible. Examples:
  67. #
  68. # class User < ActiveRecord::Base
  69. # def self.authenticate_unsafely(user_name, password)
  70. # where("user_name = '#{user_name}' AND password = '#{password}'").first
  71. # end
  72. #
  73. # def self.authenticate_safely(user_name, password)
  74. # where("user_name = ? AND password = ?", user_name, password).first
  75. # end
  76. #
  77. # def self.authenticate_safely_simply(user_name, password)
  78. # where(:user_name => user_name, :password => password).first
  79. # end
  80. # end
  81. #
  82. # The <tt>authenticate_unsafely</tt> method inserts the parameters directly into the query
  83. # and is thus susceptible to SQL-injection attacks if the <tt>user_name</tt> and +password+
  84. # parameters come directly from an HTTP request. The <tt>authenticate_safely</tt> and
  85. # <tt>authenticate_safely_simply</tt> both will sanitize the <tt>user_name</tt> and +password+
  86. # before inserting them in the query, which will ensure that an attacker can't escape the
  87. # query and fake the login (or worse).
  88. #
  89. # When using multiple parameters in the conditions, it can easily become hard to read exactly
  90. # what the fourth or fifth question mark is supposed to represent. In those cases, you can
  91. # resort to named bind variables instead. That's done by replacing the question marks with
  92. # symbols and supplying a hash with values for the matching symbol keys:
  93. #
  94. # Company.where(
  95. # "id = :id AND name = :name AND division = :division AND created_at > :accounting_date",
  96. # { :id => 3, :name => "37signals", :division => "First", :accounting_date => '2005-01-01' }
  97. # ).first
  98. #
  99. # Similarly, a simple hash without a statement will generate conditions based on equality with the SQL AND
  100. # operator. For instance:
  101. #
  102. # Student.where(:first_name => "Harvey", :status => 1)
  103. # Student.where(params[:student])
  104. #
  105. # A range may be used in the hash to use the SQL BETWEEN operator:
  106. #
  107. # Student.where(:grade => 9..12)
  108. #
  109. # An array may be used in the hash to use the SQL IN operator:
  110. #
  111. # Student.where(:grade => [9,11,12])
  112. #
  113. # When joining tables, nested hashes or keys written in the form 'table_name.column_name'
  114. # can be used to qualify the table name of a particular condition. For instance:
  115. #
  116. # Student.joins(:schools).where(:schools => { :type => 'public' })
  117. # Student.joins(:schools).where('schools.type' => 'public' )
  118. #
  119. # == Overwriting default accessors
  120. #
  121. # All column values are automatically available through basic accessors on the Active Record
  122. # object, but sometimes you want to specialize this behavior. This can be done by overwriting
  123. # the default accessors (using the same name as the attribute) and calling
  124. # <tt>read_attribute(attr_name)</tt> and <tt>write_attribute(attr_name, value)</tt> to actually
  125. # change things.
  126. #
  127. # class Song < ActiveRecord::Base
  128. # # Uses an integer of seconds to hold the length of the song
  129. #
  130. # def length=(minutes)
  131. # write_attribute(:length, minutes.to_i * 60)
  132. # end
  133. #
  134. # def length
  135. # read_attribute(:length) / 60
  136. # end
  137. # end
  138. #
  139. # You can alternatively use <tt>self[:attribute]=(value)</tt> and <tt>self[:attribute]</tt>
  140. # instead of <tt>write_attribute(:attribute, value)</tt> and <tt>read_attribute(:attribute)</tt>.
  141. #
  142. # == Attribute query methods
  143. #
  144. # In addition to the basic accessors, query methods are also automatically available on the Active Record object.
  145. # Query methods allow you to test whether an attribute value is present.
  146. #
  147. # For example, an Active Record User with the <tt>name</tt> attribute has a <tt>name?</tt> method that you can call
  148. # to determine whether the user has a name:
  149. #
  150. # user = User.new(:name => "David")
  151. # user.name? # => true
  152. #
  153. # anonymous = User.new(:name => "")
  154. # anonymous.name? # => false
  155. #
  156. # == Accessing attributes before they have been typecasted
  157. #
  158. # Sometimes you want to be able to read the raw attribute data without having the column-determined
  159. # typecast run its course first. That can be done by using the <tt><attribute>_before_type_cast</tt>
  160. # accessors that all attributes have. For example, if your Account model has a <tt>balance</tt> attribute,
  161. # you can call <tt>account.balance_before_type_cast</tt> or <tt>account.id_before_type_cast</tt>.
  162. #
  163. # This is especially useful in validation situations where the user might supply a string for an
  164. # integer field and you want to display the original string back in an error message. Accessing the
  165. # attribute normally would typecast the string to 0, which isn't what you want.
  166. #
  167. # == Dynamic attribute-based finders
  168. #
  169. # Dynamic attribute-based finders are a cleaner way of getting (and/or creating) objects
  170. # by simple queries without turning to SQL. They work by appending the name of an attribute
  171. # to <tt>find_by_</tt>, <tt>find_last_by_</tt>, or <tt>find_all_by_</tt> and thus produces finders
  172. # like <tt>Person.find_by_user_name</tt>, <tt>Person.find_all_by_last_name</tt>, and
  173. # <tt>Payment.find_by_transaction_id</tt>. Instead of writing
  174. # <tt>Person.where(:user_name => user_name).first</tt>, you just do <tt>Person.find_by_user_name(user_name)</tt>.
  175. # And instead of writing <tt>Person.where(:last_name => last_name).all</tt>, you just do
  176. # <tt>Person.find_all_by_last_name(last_name)</tt>.
  177. #
  178. # It's possible to add an exclamation point (!) on the end of the dynamic finders to get them to raise an
  179. # <tt>ActiveRecord::RecordNotFound</tt> error if they do not return any records,
  180. # like <tt>Person.find_by_last_name!</tt>.
  181. #
  182. # It's also possible to use multiple attributes in the same find by separating them with "_and_".
  183. #
  184. # Person.where(:user_name => user_name, :password => password).first
  185. # Person.find_by_user_name_and_password(user_name, password) # with dynamic finder
  186. #
  187. # It's even possible to call these dynamic finder methods on relations and named scopes.
  188. #
  189. # Payment.order("created_on").find_all_by_amount(50)
  190. # Payment.pending.find_last_by_amount(100)
  191. #
  192. # The same dynamic finder style can be used to create the object if it doesn't already exist.
  193. # This dynamic finder is called with <tt>find_or_create_by_</tt> and will return the object if
  194. # it already exists and otherwise creates it, then returns it. Protected attributes won't be set
  195. # unless they are given in a block.
  196. #
  197. # # No 'Summer' tag exists
  198. # Tag.find_or_create_by_name("Summer") # equal to Tag.create(:name => "Summer")
  199. #
  200. # # Now the 'Summer' tag does exist
  201. # Tag.find_or_create_by_name("Summer") # equal to Tag.find_by_name("Summer")
  202. #
  203. # # Now 'Bob' exist and is an 'admin'
  204. # User.find_or_create_by_name('Bob', :age => 40) { |u| u.admin = true }
  205. #
  206. # Use the <tt>find_or_initialize_by_</tt> finder if you want to return a new record without
  207. # saving it first. Protected attributes won't be set unless they are given in a block.
  208. #
  209. # # No 'Winter' tag exists
  210. # winter = Tag.find_or_initialize_by_name("Winter")
  211. # winter.persisted? # false
  212. #
  213. # To find by a subset of the attributes to be used for instantiating a new object, pass a hash instead of
  214. # a list of parameters.
  215. #
  216. # Tag.find_or_create_by_name(:name => "rails", :creator => current_user)
  217. #
  218. # That will either find an existing tag named "rails", or create a new one while setting the
  219. # user that created it.
  220. #
  221. # Just like <tt>find_by_*</tt>, you can also use <tt>scoped_by_*</tt> to retrieve data. The good thing about
  222. # using this feature is that the very first time result is returned using <tt>method_missing</tt> technique
  223. # but after that the method is declared on the class. Henceforth <tt>method_missing</tt> will not be hit.
  224. #
  225. # User.scoped_by_user_name('David')
  226. #
  227. # == Saving arrays, hashes, and other non-mappable objects in text columns
  228. #
  229. # Active Record can serialize any object in text columns using YAML. To do so, you must
  230. # specify this with a call to the class method +serialize+.
  231. # This makes it possible to store arrays, hashes, and other non-mappable objects without doing
  232. # any additional work.
  233. #
  234. # class User < ActiveRecord::Base
  235. # serialize :preferences
  236. # end
  237. #
  238. # user = User.create(:preferences => { "background" => "black", "display" => large })
  239. # User.find(user.id).preferences # => { "background" => "black", "display" => large }
  240. #
  241. # You can also specify a class option as the second parameter that'll raise an exception
  242. # if a serialized object is retrieved as a descendant of a class not in the hierarchy.
  243. #
  244. # class User < ActiveRecord::Base
  245. # serialize :preferences, Hash
  246. # end
  247. #
  248. # user = User.create(:preferences => %w( one two three ))
  249. # User.find(user.id).preferences # raises SerializationTypeMismatch
  250. #
  251. # When you specify a class option, the default value for that attribute will be a new
  252. # instance of that class.
  253. #
  254. # class User < ActiveRecord::Base
  255. # serialize :preferences, OpenStruct
  256. # end
  257. #
  258. # user = User.new
  259. # user.preferences.theme_color = "red"
  260. #
  261. #
  262. # == Single table inheritance
  263. #
  264. # Active Record allows inheritance by storing the name of the class in a column that by
  265. # default is named "type" (can be changed by overwriting <tt>Base.inheritance_column</tt>).
  266. # This means that an inheritance looking like this:
  267. #
  268. # class Company < ActiveRecord::Base; end
  269. # class Firm < Company; end
  270. # class Client < Company; end
  271. # class PriorityClient < Client; end
  272. #
  273. # When you do <tt>Firm.create(:name => "37signals")</tt>, this record will be saved in
  274. # the companies table with type = "Firm". You can then fetch this row again using
  275. # <tt>Company.where(:name => '37signals').first</tt> and it will return a Firm object.
  276. #
  277. # If you don't have a type column defined in your table, single-table inheritance won't
  278. # be triggered. In that case, it'll work just like normal subclasses with no special magic
  279. # for differentiating between them or reloading the right type with find.
  280. #
  281. # Note, all the attributes for all the cases are kept in the same table. Read more:
  282. # http://www.martinfowler.com/eaaCatalog/singleTableInheritance.html
  283. #
  284. # == Connection to multiple databases in different models
  285. #
  286. # Connections are usually created through ActiveRecord::Base.establish_connection and retrieved
  287. # by ActiveRecord::Base.connection. All classes inheriting from ActiveRecord::Base will use this
  288. # connection. But you can also set a class-specific connection. For example, if Course is an
  289. # ActiveRecord::Base, but resides in a different database, you can just say <tt>Course.establish_connection</tt>
  290. # and Course and all of its subclasses will use this connection instead.
  291. #
  292. # This feature is implemented by keeping a connection pool in ActiveRecord::Base that is
  293. # a Hash indexed by the class. If a connection is requested, the retrieve_connection method
  294. # will go up the class-hierarchy until a connection is found in the connection pool.
  295. #
  296. # == Exceptions
  297. #
  298. # * ActiveRecordError - Generic error class and superclass of all other errors raised by Active Record.
  299. # * AdapterNotSpecified - The configuration hash used in <tt>establish_connection</tt> didn't include an
  300. # <tt>:adapter</tt> key.
  301. # * AdapterNotFound - The <tt>:adapter</tt> key used in <tt>establish_connection</tt> specified a
  302. # non-existent adapter
  303. # (or a bad spelling of an existing one).
  304. # * AssociationTypeMismatch - The object assigned to the association wasn't of the type
  305. # specified in the association definition.
  306. # * SerializationTypeMismatch - The serialized object wasn't of the class specified as the second parameter.
  307. # * ConnectionNotEstablished+ - No connection has been established. Use <tt>establish_connection</tt>
  308. # before querying.
  309. # * RecordNotFound - No record responded to the +find+ method. Either the row with the given ID doesn't exist
  310. # or the row didn't meet the additional restrictions. Some +find+ calls do not raise this exception to signal
  311. # nothing was found, please check its documentation for further details.
  312. # * StatementInvalid - The database server rejected the SQL statement. The precise error is added in the message.
  313. # * MultiparameterAssignmentErrors - Collection of errors that occurred during a mass assignment using the
  314. # <tt>attributes=</tt> method. The +errors+ property of this exception contains an array of
  315. # AttributeAssignmentError
  316. # objects that should be inspected to determine which attributes triggered the errors.
  317. # * AttributeAssignmentError - An error occurred while doing a mass assignment through the
  318. # <tt>attributes=</tt> method.
  319. # You can inspect the +attribute+ property of the exception object to determine which attribute
  320. # triggered the error.
  321. #
  322. # *Note*: The attributes listed are class-level attributes (accessible from both the class and instance level).
  323. # So it's possible to assign a logger to the class through <tt>Base.logger=</tt> which will then be used by all
  324. # instances in the current object space.
  325. class Base
  326. ##
  327. # :singleton-method:
  328. # Accepts a logger conforming to the interface of Log4r or the default Ruby 1.8+ Logger class,
  329. # which is then passed on to any new database connections made and which can be retrieved on both
  330. # a class and instance level by calling +logger+.
  331. cattr_accessor :logger, :instance_writer => false
  332. ##
  333. # :singleton-method:
  334. # Contains the database configuration - as is typically stored in config/database.yml -
  335. # as a Hash.
  336. #
  337. # For example, the following database.yml...
  338. #
  339. # development:
  340. # adapter: sqlite3
  341. # database: db/development.sqlite3
  342. #
  343. # production:
  344. # adapter: sqlite3
  345. # database: db/production.sqlite3
  346. #
  347. # ...would result in ActiveRecord::Base.configurations to look like this:
  348. #
  349. # {
  350. # 'development' => {
  351. # 'adapter' => 'sqlite3',
  352. # 'database' => 'db/development.sqlite3'
  353. # },
  354. # 'production' => {
  355. # 'adapter' => 'sqlite3',
  356. # 'database' => 'db/production.sqlite3'
  357. # }
  358. # }
  359. cattr_accessor :configurations, :instance_writer => false
  360. @@configurations = {}
  361. ##
  362. # :singleton-method:
  363. # Accessor for the prefix type that will be prepended to every primary key column name.
  364. # The options are :table_name and :table_name_with_underscore. If the first is specified,
  365. # the Product class will look for "productid" instead of "id" as the primary column. If the
  366. # latter is specified, the Product class will look for "product_id" instead of "id". Remember
  367. # that this is a global setting for all Active Records.
  368. cattr_accessor :primary_key_prefix_type, :instance_writer => false
  369. @@primary_key_prefix_type = nil
  370. ##
  371. # :singleton-method:
  372. # Accessor for the name of the prefix string to prepend to every table name. So if set
  373. # to "basecamp_", all table names will be named like "basecamp_projects", "basecamp_people",
  374. # etc. This is a convenient way of creating a namespace for tables in a shared database.
  375. # By default, the prefix is the empty string.
  376. #
  377. # If you are organising your models within modules you can add a prefix to the models within
  378. # a namespace by defining a singleton method in the parent module called table_name_prefix which
  379. # returns your chosen prefix.
  380. class_attribute :table_name_prefix, :instance_writer => false
  381. self.table_name_prefix = ""
  382. ##
  383. # :singleton-method:
  384. # Works like +table_name_prefix+, but appends instead of prepends (set to "_basecamp" gives "projects_basecamp",
  385. # "people_basecamp"). By default, the suffix is the empty string.
  386. class_attribute :table_name_suffix, :instance_writer => false
  387. self.table_name_suffix = ""
  388. ##
  389. # :singleton-method:
  390. # Indicates whether table names should be the pluralized versions of the corresponding class names.
  391. # If true, the default table name for a Product class will be +products+. If false, it would just be +product+.
  392. # See table_name for the full rules on table/class naming. This is true, by default.
  393. class_attribute :pluralize_table_names, :instance_writer => false
  394. self.pluralize_table_names = true
  395. ##
  396. # :singleton-method:
  397. # Determines whether to use Time.local (using :local) or Time.utc (using :utc) when pulling
  398. # dates and times from the database. This is set to :local by default.
  399. cattr_accessor :default_timezone, :instance_writer => false
  400. @@default_timezone = :local
  401. ##
  402. # :singleton-method:
  403. # Specifies the format to use when dumping the database schema with Rails'
  404. # Rakefile. If :sql, the schema is dumped as (potentially database-
  405. # specific) SQL statements. If :ruby, the schema is dumped as an
  406. # ActiveRecord::Schema file which can be loaded into any database that
  407. # supports migrations. Use :ruby if you want to have different database
  408. # adapters for, e.g., your development and test environments.
  409. cattr_accessor :schema_format , :instance_writer => false
  410. @@schema_format = :ruby
  411. ##
  412. # :singleton-method:
  413. # Specify whether or not to use timestamps for migration versions
  414. cattr_accessor :timestamped_migrations , :instance_writer => false
  415. @@timestamped_migrations = true
  416. # Determine whether to store the full constant name including namespace when using STI
  417. class_attribute :store_full_sti_class
  418. self.store_full_sti_class = true
  419. # Stores the default scope for the class
  420. class_attribute :default_scopes, :instance_writer => false
  421. self.default_scopes = []
  422. # Returns a hash of all the attributes that have been specified for serialization as
  423. # keys and their class restriction as values.
  424. class_attribute :serialized_attributes
  425. self.serialized_attributes = {}
  426. class_attribute :_attr_readonly, :instance_writer => false
  427. self._attr_readonly = []
  428. class << self # Class methods
  429. delegate :find, :first, :first!, :last, :last!, :all, :exists?, :any?, :many?, :to => :scoped
  430. delegate :first_or_create, :first_or_create!, :first_or_initialize, :to => :scoped
  431. delegate :destroy, :destroy_all, :delete, :delete_all, :update, :update_all, :to => :scoped
  432. delegate :find_each, :find_in_batches, :to => :scoped
  433. delegate :select, :group, :order, :except, :reorder, :limit, :offset, :joins, :where, :preload, :eager_load, :includes, :from, :lock, :readonly, :having, :create_with, :to => :scoped
  434. delegate :count, :average, :minimum, :maximum, :sum, :calculate, :to => :scoped
  435. # Executes a custom SQL query against your database and returns all the results. The results will
  436. # be returned as an array with columns requested encapsulated as attributes of the model you call
  437. # this method from. If you call <tt>Product.find_by_sql</tt> then the results will be returned in
  438. # a Product object with the attributes you specified in the SQL query.
  439. #
  440. # If you call a complicated SQL query which spans multiple tables the columns specified by the
  441. # SELECT will be attributes of the model, whether or not they are columns of the corresponding
  442. # table.
  443. #
  444. # The +sql+ parameter is a full SQL query as a string. It will be called as is, there will be
  445. # no database agnostic conversions performed. This should be a last resort because using, for example,
  446. # MySQL specific terms will lock you to using that particular database engine or require you to
  447. # change your call if you switch engines.
  448. #
  449. # ==== Examples
  450. # # A simple SQL query spanning multiple tables
  451. # Post.find_by_sql "SELECT p.title, c.author FROM posts p, comments c WHERE p.id = c.post_id"
  452. # > [#<Post:0x36bff9c @attributes={"title"=>"Ruby Meetup", "first_name"=>"Quentin"}>, ...]
  453. #
  454. # # You can use the same string replacement techniques as you can with ActiveRecord#find
  455. # Post.find_by_sql ["SELECT title FROM posts WHERE author = ? AND created > ?", author_id, start_date]
  456. # > [#<Post:0x36bff9c @attributes={"title"=>"The Cheap Man Buys Twice"}>, ...]
  457. def find_by_sql(sql, binds = [])
  458. connection.select_all(sanitize_sql(sql), "#{name} Load", binds).collect! { |record| instantiate(record) }
  459. end
  460. # Creates an object (or multiple objects) and saves it to the database, if validations pass.
  461. # The resulting object is returned whether the object was saved successfully to the database or not.
  462. #
  463. # The +attributes+ parameter can be either be a Hash or an Array of Hashes. These Hashes describe the
  464. # attributes on the objects that are to be created.
  465. #
  466. # +create+ respects mass-assignment security and accepts either +:as+ or +:without_protection+ options
  467. # in the +options+ parameter.
  468. #
  469. # ==== Examples
  470. # # Create a single new object
  471. # User.create(:first_name => 'Jamie')
  472. #
  473. # # Create a single new object using the :admin mass-assignment security role
  474. # User.create({ :first_name => 'Jamie', :is_admin => true }, :as => :admin)
  475. #
  476. # # Create a single new object bypassing mass-assignment security
  477. # User.create({ :first_name => 'Jamie', :is_admin => true }, :without_protection => true)
  478. #
  479. # # Create an Array of new objects
  480. # User.create([{ :first_name => 'Jamie' }, { :first_name => 'Jeremy' }])
  481. #
  482. # # Create a single object and pass it into a block to set other attributes.
  483. # User.create(:first_name => 'Jamie') do |u|
  484. # u.is_admin = false
  485. # end
  486. #
  487. # # Creating an Array of new objects using a block, where the block is executed for each object:
  488. # User.create([{ :first_name => 'Jamie' }, { :first_name => 'Jeremy' }]) do |u|
  489. # u.is_admin = false
  490. # end
  491. def create(attributes = nil, options = {}, &block)
  492. if attributes.is_a?(Array)
  493. attributes.collect { |attr| create(attr, options, &block) }
  494. else
  495. object = new(attributes, options, &block)
  496. object.save
  497. object
  498. end
  499. end
  500. # Returns the result of an SQL statement that should only include a COUNT(*) in the SELECT part.
  501. # The use of this method should be restricted to complicated SQL queries that can't be executed
  502. # using the ActiveRecord::Calculations class methods. Look into those before using this.
  503. #
  504. # ==== Parameters
  505. #
  506. # * +sql+ - An SQL statement which should return a count query from the database, see the example below.
  507. #
  508. # ==== Examples
  509. #
  510. # Product.count_by_sql "SELECT COUNT(*) FROM sales s, customers c WHERE s.customer_id = c.id"
  511. def count_by_sql(sql)
  512. sql = sanitize_conditions(sql)
  513. connection.select_value(sql, "#{name} Count").to_i
  514. end
  515. # Attributes listed as readonly will be used to create a new record but update operations will
  516. # ignore these fields.
  517. def attr_readonly(*attributes)
  518. self._attr_readonly = Set.new(attributes.map { |a| a.to_s }) + (self._attr_readonly || [])
  519. end
  520. # Returns an array of all the attributes that have been specified as readonly.
  521. def readonly_attributes
  522. self._attr_readonly
  523. end
  524. # If you have an attribute that needs to be saved to the database as an object, and retrieved as the same object,
  525. # then specify the name of that attribute using this method and it will be handled automatically.
  526. # The serialization is done through YAML. If +class_name+ is specified, the serialized object must be of that
  527. # class on retrieval or SerializationTypeMismatch will be raised.
  528. #
  529. # ==== Parameters
  530. #
  531. # * +attr_name+ - The field name that should be serialized.
  532. # * +class_name+ - Optional, class name that the object type should be equal to.
  533. #
  534. # ==== Example
  535. # # Serialize a preferences attribute
  536. # class User < ActiveRecord::Base
  537. # serialize :preferences
  538. # end
  539. def serialize(attr_name, class_name = Object)
  540. coder = if [:load, :dump].all? { |x| class_name.respond_to?(x) }
  541. class_name
  542. else
  543. Coders::YAMLColumn.new(class_name)
  544. end
  545. # merge new serialized attribute and create new hash to ensure that each class in inheritance hierarchy
  546. # has its own hash of own serialized attributes
  547. self.serialized_attributes = serialized_attributes.merge(attr_name.to_s => coder)
  548. end
  549. # Guesses the table name (in forced lower-case) based on the name of the class in the
  550. # inheritance hierarchy descending directly from ActiveRecord::Base. So if the hierarchy
  551. # looks like: Reply < Message < ActiveRecord::Base, then Message is used
  552. # to guess the table name even when called on Reply. The rules used to do the guess
  553. # are handled by the Inflector class in Active Support, which knows almost all common
  554. # English inflections. You can add new inflections in config/initializers/inflections.rb.
  555. #
  556. # Nested classes are given table names prefixed by the singular form of
  557. # the parent's table name. Enclosing modules are not considered.
  558. #
  559. # ==== Examples
  560. #
  561. # class Invoice < ActiveRecord::Base
  562. # end
  563. #
  564. # file class table_name
  565. # invoice.rb Invoice invoices
  566. #
  567. # class Invoice < ActiveRecord::Base
  568. # class Lineitem < ActiveRecord::Base
  569. # end
  570. # end
  571. #
  572. # file class table_name
  573. # invoice.rb Invoice::Lineitem invoice_lineitems
  574. #
  575. # module Invoice
  576. # class Lineitem < ActiveRecord::Base
  577. # end
  578. # end
  579. #
  580. # file class table_name
  581. # invoice/lineitem.rb Invoice::Lineitem lineitems
  582. #
  583. # Additionally, the class-level +table_name_prefix+ is prepended and the
  584. # +table_name_suffix+ is appended. So if you have "myapp_" as a prefix,
  585. # the table name guess for an Invoice class becomes "myapp_invoices".
  586. # Invoice::Lineitem becomes "myapp_invoice_lineitems".
  587. #
  588. # You can also overwrite this class method to allow for unguessable
  589. # links, such as a Mouse class with a link to a "mice" table. Example:
  590. #
  591. # class Mouse < ActiveRecord::Base
  592. # set_table_name "mice"
  593. # end
  594. def table_name
  595. reset_table_name
  596. end
  597. # Returns a quoted version of the table name, used to construct SQL statements.
  598. def quoted_table_name
  599. @quoted_table_name ||= connection.quote_table_name(table_name)
  600. end
  601. # Computes the table name, (re)sets it internally, and returns it.
  602. def reset_table_name #:nodoc:
  603. return if abstract_class?
  604. self.table_name = compute_table_name
  605. end
  606. def full_table_name_prefix #:nodoc:
  607. (parents.detect{ |p| p.respond_to?(:table_name_prefix) } || self).table_name_prefix
  608. end
  609. # Defines the column name for use with single table inheritance. Use
  610. # <tt>set_inheritance_column</tt> to set a different value.
  611. def inheritance_column
  612. @inheritance_column ||= "type"
  613. end
  614. # Lazy-set the sequence name to the connection's default. This method
  615. # is only ever called once since set_sequence_name overrides it.
  616. def sequence_name #:nodoc:
  617. reset_sequence_name
  618. end
  619. def reset_sequence_name #:nodoc:
  620. default = connection.default_sequence_name(table_name, primary_key)
  621. set_sequence_name(default)
  622. default
  623. end
  624. # Sets the table name. If the value is nil or false then the value returned by the given
  625. # block is used.
  626. #
  627. # class Project < ActiveRecord::Base
  628. # set_table_name "project"
  629. # end
  630. def set_table_name(value = nil, &block)
  631. @quoted_table_name = nil
  632. define_attr_method :table_name, value, &block
  633. @arel_table = nil
  634. @relation = Relation.new(self, arel_table)
  635. end
  636. alias :table_name= :set_table_name
  637. # Sets the name of the inheritance column to use to the given value,
  638. # or (if the value # is nil or false) to the value returned by the
  639. # given block.
  640. #
  641. # class Project < ActiveRecord::Base
  642. # set_inheritance_column do
  643. # original_inheritance_column + "_id"
  644. # end
  645. # end
  646. def set_inheritance_column(value = nil, &block)
  647. define_attr_method :inheritance_column, value, &block
  648. end
  649. alias :inheritance_column= :set_inheritance_column
  650. # Sets the name of the sequence to use when generating ids to the given
  651. # value, or (if the value is nil or false) to the value returned by the
  652. # given block. This is required for Oracle and is useful for any
  653. # database which relies on sequences for primary key generation.
  654. #
  655. # If a sequence name is not explicitly set when using Oracle or Firebird,
  656. # it will default to the commonly used pattern of: #{table_name}_seq
  657. #
  658. # If a sequence name is not explicitly set when using PostgreSQL, it
  659. # will discover the sequence corresponding to your primary key for you.
  660. #
  661. # class Project < ActiveRecord::Base
  662. # set_sequence_name "projectseq" # default would have been "project_seq"
  663. # end
  664. def set_sequence_name(value = nil, &block)
  665. define_attr_method :sequence_name, value, &block
  666. end
  667. alias :sequence_name= :set_sequence_name
  668. # Indicates whether the table associated with this class exists
  669. def table_exists?
  670. connection.table_exists?(table_name)
  671. end
  672. # Returns an array of column objects for the table associated with this class.
  673. def columns
  674. connection_pool.columns[table_name]
  675. end
  676. # Returns a hash of column objects for the table associated with this class.
  677. def columns_hash
  678. connection_pool.columns_hash[table_name]
  679. end
  680. # Returns a hash where the keys are column names and the values are
  681. # default values when instantiating the AR object for this table.
  682. def column_defaults
  683. connection_pool.column_defaults[table_name]
  684. end
  685. # Returns an array of column names as strings.
  686. def column_names
  687. @column_names ||= columns.map { |column| column.name }
  688. end
  689. # Returns an array of column objects where the primary id, all columns ending in "_id" or "_count",
  690. # and columns used for single table inheritance have been removed.
  691. def content_columns
  692. @content_columns ||= columns.reject { |c| c.primary || c.name =~ /(_id|_count)$/ || c.name == inheritance_column }
  693. end
  694. # 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
  695. # 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
  696. # is available.
  697. def column_methods_hash #:nodoc:
  698. @dynamic_methods_hash ||= column_names.inject(Hash.new(false)) do |methods, attr|
  699. attr_name = attr.to_s
  700. methods[attr.to_sym] = attr_name
  701. methods["#{attr}=".to_sym] = attr_name
  702. methods["#{attr}?".to_sym] = attr_name
  703. methods["#{attr}_before_type_cast".to_sym] = attr_name
  704. methods
  705. end
  706. end
  707. # Resets all the cached information about columns, which will cause them
  708. # to be reloaded on the next request.
  709. #
  710. # The most common usage pattern for this method is probably in a migration,
  711. # when just after creating a table you want to populate it with some default
  712. # values, eg:
  713. #
  714. # class CreateJobLevels < ActiveRecord::Migration
  715. # def self.up
  716. # create_table :job_levels do |t|
  717. # t.integer :id
  718. # t.string :name
  719. #
  720. # t.timestamps
  721. # end
  722. #
  723. # JobLevel.reset_column_information
  724. # %w{assistant executive manager director}.each do |type|
  725. # JobLevel.create(:name => type)
  726. # end
  727. # end
  728. #
  729. # def self.down
  730. # drop_table :job_levels
  731. # end
  732. # end
  733. def reset_column_information
  734. connection.clear_cache!
  735. undefine_attribute_methods
  736. connection_pool.clear_table_cache!(table_name) if table_exists?
  737. @column_names = @content_columns = @dynamic_methods_hash = @inheritance_column = nil
  738. @arel_engine = @relation = nil
  739. end
  740. def clear_cache! # :nodoc:
  741. connection_pool.clear_cache!
  742. end
  743. def attribute_method?(attribute)
  744. super || (table_exists? && column_names.include?(attribute.to_s.sub(/=$/, '')))
  745. end
  746. # Returns an array of column names as strings if it's not
  747. # an abstract class and table exists.
  748. # Otherwise it returns an empty array.
  749. def attribute_names
  750. @attribute_names ||= if !abstract_class? && table_exists?
  751. column_names
  752. else
  753. []
  754. end
  755. end
  756. # Set the lookup ancestors for ActiveModel.
  757. def lookup_ancestors #:nodoc:
  758. klass = self
  759. classes = [klass]
  760. return classes if klass == ActiveRecord::Base
  761. while klass != klass.base_class
  762. classes << klass = klass.superclass
  763. end
  764. classes
  765. end
  766. # Set the i18n scope to overwrite ActiveModel.
  767. def i18n_scope #:nodoc:
  768. :activerecord
  769. end
  770. # True if this isn't a concrete subclass needing a STI type condition.
  771. def descends_from_active_record?
  772. if superclass.abstract_class?
  773. superclass.descends_from_active_record?
  774. else
  775. superclass == Base || !columns_hash.include?(inheritance_column)
  776. end
  777. end
  778. def finder_needs_type_condition? #:nodoc:
  779. # This is like this because benchmarking justifies the strange :false stuff
  780. :true == (@finder_needs_type_condition ||= descends_from_active_record? ? :false : :true)
  781. end
  782. # Returns a string like 'Post(id:integer, title:string, body:text)'
  783. def inspect
  784. if self == Base
  785. super
  786. elsif abstract_class?
  787. "#{super}(abstract)"
  788. elsif table_exists?
  789. attr_list = columns.map { |c| "#{c.name}: #{c.type}" } * ', '
  790. "#{super}(#{attr_list})"
  791. else
  792. "#{super}(Table doesn't exist)"
  793. end
  794. end
  795. def quote_value(value, column = nil) #:nodoc:
  796. connection.quote(value,column)
  797. end
  798. # Used to sanitize objects before they're used in an SQL SELECT statement. Delegates to <tt>connection.quote</tt>.
  799. def sanitize(object) #:nodoc:
  800. connection.quote(object)
  801. end
  802. # Overwrite the default class equality method to provide support for association proxies.
  803. def ===(object)
  804. object.is_a?(self)
  805. end
  806. def symbolized_base_class
  807. @symbolized_base_class ||= base_class.to_s.to_sym
  808. end
  809. def symbolized_sti_name
  810. @symbolized_sti_name ||= sti_name.present? ? sti_name.to_sym : symbolized_base_class
  811. end
  812. # Returns the base AR subclass that this class descends from. If A
  813. # extends AR::Base, A.base_class will return A. If B descends from A
  814. # through some arbitrarily deep hierarchy, B.base_class will return A.
  815. #
  816. # If B < A and C < B and if A is an abstract_class then both B.base_class
  817. # and C.base_class would return B as the answer since A is an abstract_class.
  818. def base_class
  819. class_of_active_record_descendant(self)
  820. end
  821. # Set this to true if this is an abstract class (see <tt>abstract_class?</tt>).
  822. attr_accessor :abstract_class
  823. # Returns whether this class is an abstract class or not.
  824. def abstract_class?
  825. defined?(@abstract_class) && @abstract_class == true
  826. end
  827. def respond_to?(method_id, include_private = false)
  828. if match = DynamicFinderMatch.match(method_id)
  829. return true if all_attributes_exists?(match.attribute_names)
  830. elsif match = DynamicScopeMatch.match(method_id)
  831. return true if all_attributes_exists?(match.attribute_names)
  832. end
  833. super
  834. end
  835. def sti_name
  836. store_full_sti_class ? name : name.demodulize
  837. end
  838. def arel_table
  839. @arel_table ||= Arel::Table.new(table_name, arel_engine)
  840. end
  841. def arel_engine
  842. @arel_engine ||= begin
  843. if self == ActiveRecord::Base
  844. ActiveRecord::Base
  845. else
  846. connection_handler.connection_pools[name] ? self : superclass.arel_engine
  847. end
  848. end
  849. end
  850. # Returns a scope for this class without taking into account the default_scope.
  851. #
  852. # class Post < ActiveRecord::Base
  853. # def self.default_scope
  854. # where :published => true
  855. # end
  856. # end
  857. #
  858. # Post.all # Fires "SELECT * FROM posts WHERE published = true"
  859. # Post.unscoped.all # Fires "SELECT * FROM posts"
  860. #
  861. # This method also accepts a block meaning that all queries inside the block will
  862. # not use the default_scope:
  863. #
  864. # Post.unscoped {
  865. # Post.limit(10) # Fires "SELECT * FROM posts LIMIT 10"
  866. # }
  867. #
  868. # It is recommended to use block form of unscoped because chaining unscoped with <tt>scope</tt>
  869. # does not work. Assuming that <tt>published</tt> is a <tt>scope</tt> following two statements are same.
  870. #
  871. # Post.unscoped.published
  872. # Post.published
  873. def unscoped #:nodoc:
  874. block_given? ? relation.scoping { yield } : relation
  875. end
  876. def before_remove_const #:nodoc:
  877. self.current_scope = nil
  878. end
  879. # Finder methods must instantiate through this method to work with the
  880. # single-table inheritance model that makes it possible to create
  881. # objects of different types from the same table.
  882. def instantiate(record)
  883. sti_class = find_sti_class(record[inheritance_column])
  884. record_id = sti_class.primary_key && record[sti_class.primary_key]
  885. if ActiveRecord::IdentityMap.enabled? && record_id
  886. if (column = sti_class.columns_hash[sti_class.primary_key]) && column.number?
  887. record_id = record_id.to_i
  888. end
  889. if instance = IdentityMap.get(sti_class, record_id)
  890. instance.reinit_with('attributes' => record)
  891. else
  892. instance = sti_class.allocate.init_with('attributes' => record)
  893. IdentityMap.add(instance)
  894. end
  895. else
  896. instance = sti_class.allocate.init_with('attributes' => record)
  897. end
  898. instance
  899. end
  900. private
  901. def relation #:nodoc:
  902. @relation ||= Relation.new(self, arel_table)
  903. if finder_needs_type_condition?
  904. @relation.where(type_condition).create_with(inheritance_column.to_sym => sti_name)
  905. else
  906. @relation
  907. end
  908. end
  909. def find_sti_class(type_name)
  910. if type_name.blank? || !columns_hash.include?(inheritance_column)
  911. self
  912. else
  913. begin
  914. if store_full_sti_class
  915. ActiveSupport::Dependencies.constantize(type_name)
  916. else
  917. compute_type(type_name)
  918. end
  919. rescue NameError
  920. raise SubclassNotFound,
  921. "The single-table inheritance mechanism failed to locate the subclass: '#{type_name}'. " +
  922. "This error is raised because the column '#{inheritance_column}' is reserved for storing the class in case of inheritance. " +
  923. "Please rename this column if you didn't intend it to be used for storing the inheritance class " +
  924. "or overwrite #{name}.inheritance_column to use another column for that information."
  925. end
  926. end
  927. end
  928. def construct_finder_arel(options = {}, scope = nil)
  929. relation = options.is_a?(Hash) ? unscoped.apply_finder_options(options) : options
  930. relation = scope.merge(relation) if scope
  931. relation
  932. end
  933. def type_condition(table = arel_table)
  934. sti_column = table[inheritance_column.to_sym]
  935. sti_names = ([self] + descendants).map { |model| model.sti_name }
  936. sti_column.in(sti_names)
  937. end
  938. # Guesses the table name, but does not decorate it with prefix and suffix information.
  939. def undecorated_table_name(class_name = base_class.name)
  940. table_name = class_name.to_s.demodulize.underscore
  941. table_name = table_name.pluralize if pluralize_table_names
  942. table_name
  943. end
  944. # Computes and returns a table name according to default conventions.
  945. def compute_table_name
  946. base = base_class
  947. if self == base
  948. # Nested classes are prefixed with singular parent table name.
  949. if parent < ActiveRecord::Base && !parent.abstract_class?
  950. contained = parent.table_name
  951. contained = contained.singularize if parent.pluralize_table_names
  952. contained += '_'
  953. end
  954. "#{full_table_name_prefix}#{contained}#{undecorated_table_name(name)}#{table_name_suffix}"
  955. else
  956. # STI subclasses always use their superclass' table.
  957. base.table_name
  958. end
  959. end
  960. # Enables dynamic finders like <tt>User.find_by_user_name(user_name)</tt> and
  961. # <tt>User.scoped_by_user_name(user_name). Refer to Dynamic attribute-based finders
  962. # section at the top of this file for more detailed information.
  963. #
  964. # It's even possible to use all the additional parameters to +find+. For example, the
  965. # full interface for +find_all_by_amount+ is actually <tt>find_all_by_amount(amount, options)</tt>.
  966. #
  967. # Each dynamic finder using <tt>scoped_by_*</tt> is also defined in the class after it
  968. # is first invoked, so that future attempts to use it do not run through method_missing.
  969. def method_missing(method_id, *arguments, &block)
  970. if match = (DynamicFinderMatch.match(method_id) || DynamicScopeMatch.match(method_id))
  971. attribute_names = match.attribute_names
  972. super unless all_attributes_exists?(attribute_names)
  973. if arguments.size < attribute_names.size
  974. method_trace = "#{__FILE__}:#{__LINE__}:in `#{method_id}'"
  975. backtrace = [method_trace] + caller
  976. raise ArgumentError, "wrong number of arguments (#{arguments.size} for #{attribute_names.size})", backtrace
  977. end
  978. if match.respond_to?(:scope?) && match.scope?
  979. self.class_eval <<-METHOD, __FILE__, __LINE__ + 1
  980. def self.#{method_id}(*args) # def self.scoped_by_user_name_and_password(*args)
  981. attributes = Hash[[:#{attribute_names.join(',:')}].zip(args)] # attributes = Hash[[:user_name, :password].zip(args)]
  982. #
  983. scoped(:conditions => attributes) # scoped(:conditions => attributes)
  984. end # end
  985. METHOD
  986. send(method_id, *arguments)
  987. elsif match.finder?
  988. options = arguments.extract_options!
  989. relation = options.any? ? scoped(options) : scoped
  990. relation.send :find_by_attributes, match, attribute_names, *arguments, &block
  991. elsif match.instantiator?
  992. scoped.send :find_or_instantiator_by_attributes, match, attribute_names, *arguments, &block
  993. end
  994. else
  995. super
  996. end
  997. end
  998. # Similar in purpose to +expand_hash_conditions_for_aggregates+.
  999. def expand_attribute_names_for_aggregates(attribute_names)
  1000. attribute_names.map { |attribute_name|
  1001. unless (aggregation = reflect_on_aggregation(attribute_name.to_sym)).nil?
  1002. aggregate_mapping(aggregation).map do |field_attr, _|
  1003. field_attr.to_sym
  1004. end
  1005. else
  1006. attribute_name.to_sym
  1007. end
  1008. }.flatten
  1009. end
  1010. def all_attributes_exists?(attribute_names)
  1011. (expand_attribute_names_for_aggregates(attribute_names) -
  1012. column_methods_hash.keys).empty?
  1013. end
  1014. protected
  1015. # with_scope lets you apply options to inner block incrementally. It takes a hash and the keys must be
  1016. # <tt>:find</tt> or <tt>:create</tt>. <tt>:find</tt> parameter is <tt>Relation</tt> while
  1017. # <tt>:create</tt> parameters are an attributes hash.
  1018. #
  1019. # class Article < ActiveRecord::Base
  1020. # def self.create_with_scope
  1021. # with_scope(:find => where(:blog_id => 1), :create => { :blog_id => 1 }) do
  1022. # find(1) # => SELECT * from articles WHERE blog_id = 1 AND id = 1
  1023. # a = create(1)
  1024. # a.blog_id # => 1
  1025. # end
  1026. # end
  1027. # end
  1028. #
  1029. # In nested scopings, all previous parameters are overwritten by the innermost rule, with the exception of
  1030. # <tt>where</tt>, <tt>includes</tt>, and <tt>joins</tt> operations in <tt>Relation</tt>, which are merged.
  1031. #
  1032. # <tt>joins</tt> operations are uniqued so multiple scopes can join in the same table without table aliasing
  1033. # problems. If you need to join multiple tables, but still want one of the tables to be uniqued, use the
  1034. # array of strings format for your joins.
  1035. #
  1036. # class Article < ActiveRecord::Base
  1037. # def self.find_with_scope
  1038. # with_scope(:find => where(:blog_id => 1).limit(1), :create => { :blog_id => 1 }) do
  1039. # with_scope(:find => limit(10)) do
  1040. # all # => SELECT * from articles WHERE blog_id = 1 LIMIT 10
  1041. # end
  1042. # with_scope(:find => where(:author_id => 3)) do
  1043. # all # => SELECT * from articles WHERE blog_id = 1 AND author_id = 3 LIMIT 1
  1044. # end
  1045. # end
  1046. # end
  1047. # end
  1048. #
  1049. # You can ignore any previous scopings by using the <tt>with_exclusive_scope</tt> method.
  1050. #
  1051. # class Article < ActiveRecord::Base
  1052. # def sel