From 9465b84b543ae1ada29c0e39e34f919c724eab6d Mon Sep 17 00:00:00 2001 From: Pratik Naik Date: Tue, 19 Jan 2010 22:15:35 +0530 Subject: Rename CalculationMethods to Calculations and get rid of the old Calculations module --- activerecord/lib/active_record/base.rb | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'activerecord/lib/active_record/base.rb') diff --git a/activerecord/lib/active_record/base.rb b/activerecord/lib/active_record/base.rb index 06244d1132..e10df1abd3 100755 --- a/activerecord/lib/active_record/base.rb +++ b/activerecord/lib/active_record/base.rb @@ -654,6 +654,7 @@ module ActiveRecord #:nodoc: end delegate :select, :group, :order, :limit, :joins, :where, :preload, :eager_load, :includes, :from, :lock, :readonly, :having, :to => :scoped + delegate :count, :average, :minimum, :maximum, :sum, :calculate, :to => :scoped # A convenience wrapper for find(:first, *args). You can pass in all the # same arguments to this method as you can to find(:first). @@ -2742,7 +2743,7 @@ module ActiveRecord #:nodoc: # #save_with_autosave_associations to be wrapped inside a transaction. include AutosaveAssociation, NestedAttributes - include Aggregations, Transactions, Reflection, Batches, Calculations, Serialization + include Aggregations, Transactions, Reflection, Batches, Serialization end end -- cgit v1.2.3 From 1b78a3f8d5417708eb7040cc00722494eaa6a2b5 Mon Sep 17 00:00:00 2001 From: Pratik Naik Date: Wed, 20 Jan 2010 01:29:18 +0530 Subject: with_scope no longer needs :reverse_merge --- activerecord/lib/active_record/base.rb | 15 ++------------- 1 file changed, 2 insertions(+), 13 deletions(-) (limited to 'activerecord/lib/active_record/base.rb') diff --git a/activerecord/lib/active_record/base.rb b/activerecord/lib/active_record/base.rb index e10df1abd3..c20a14551e 100755 --- a/activerecord/lib/active_record/base.rb +++ b/activerecord/lib/active_record/base.rb @@ -1763,11 +1763,8 @@ module ActiveRecord #:nodoc: relation = construct_finder_arel(method_scoping[:find] || {}) if current_scoped_methods && current_scoped_methods.create_with_value && method_scoping[:create] - scope_for_create = case action - when :merge + scope_for_create = if action == :merge current_scoped_methods.create_with_value.merge(method_scoping[:create]) - when :reverse_merge - method_scoping[:create].merge(current_scoped_methods.create_with_value) else method_scoping[:create] end @@ -1782,15 +1779,7 @@ module ActiveRecord #:nodoc: method_scoping = relation end - if current_scoped_methods - case action - when :merge - method_scoping = current_scoped_methods.merge(method_scoping) - when :reverse_merge - method_scoping = current_scoped_methods.except(:where).merge(method_scoping) - method_scoping = method_scoping.merge(current_scoped_methods.only(:where)) - end - end + method_scoping = current_scoped_methods.merge(method_scoping) if current_scoped_methods && action == :merge self.scoped_methods << method_scoping begin -- cgit v1.2.3 From 52ec4311f5bf8b596612f297da0b3be8e284b038 Mon Sep 17 00:00:00 2001 From: Pratik Naik Date: Wed, 20 Jan 2010 03:35:25 +0530 Subject: Delegate all finders to Relation --- activerecord/lib/active_record/base.rb | 116 +-------------------------------- 1 file changed, 1 insertion(+), 115 deletions(-) (limited to 'activerecord/lib/active_record/base.rb') diff --git a/activerecord/lib/active_record/base.rb b/activerecord/lib/active_record/base.rb index c20a14551e..6063c9789f 100755 --- a/activerecord/lib/active_record/base.rb +++ b/activerecord/lib/active_record/base.rb @@ -556,124 +556,10 @@ module ActiveRecord #:nodoc: end alias :colorize_logging= :colorize_logging - # Find operates with four different retrieval approaches: - # - # * Find by id - This can either be a specific id (1), a list of ids (1, 5, 6), or an array of ids ([5, 6, 10]). - # If no record can be found for all of the listed ids, then RecordNotFound will be raised. - # * Find first - This will return the first record matched by the options used. These options can either be specific - # conditions or merely an order. If no record can be matched, +nil+ is returned. Use - # Model.find(:first, *args) or its shortcut Model.first(*args). - # * Find last - This will return the last record matched by the options used. These options can either be specific - # conditions or merely an order. If no record can be matched, +nil+ is returned. Use - # Model.find(:last, *args) or its shortcut Model.last(*args). - # * Find all - This will return all the records matched by the options used. - # If no records are found, an empty array is returned. Use - # Model.find(:all, *args) or its shortcut Model.all(*args). - # - # All approaches accept an options hash as their last parameter. - # - # ==== Parameters - # - # * :conditions - An SQL fragment like "administrator = 1", [ "user_name = ?", username ], or ["user_name = :user_name", { :user_name => user_name }]. See conditions in the intro. - # * :order - An SQL fragment like "created_at DESC, name". - # * :group - An attribute name by which the result should be grouped. Uses the GROUP BY SQL-clause. - # * :having - Combined with +:group+ this can be used to filter the records that a GROUP BY returns. Uses the HAVING SQL-clause. - # * :limit - An integer determining the limit on the number of rows that should be returned. - # * :offset - An integer determining the offset from where the rows should be fetched. So at 5, it would skip rows 0 through 4. - # * :joins - Either an SQL fragment for additional joins like "LEFT JOIN comments ON comments.post_id = id" (rarely needed), - # named associations in the same form used for the :include option, which will perform an INNER JOIN on the associated table(s), - # or an array containing a mixture of both strings and named associations. - # If the value is a string, then the records will be returned read-only since they will have attributes that do not correspond to the table's columns. - # Pass :readonly => false to override. - # * :include - Names associations that should be loaded alongside. The symbols named refer - # to already defined associations. See eager loading under Associations. - # * :select - By default, this is "*" as in "SELECT * FROM", but can be changed if you, for example, want to do a join but not - # include the joined columns. Takes a string with the SELECT SQL fragment (e.g. "id, name"). - # * :from - By default, this is the table name of the class, but can be changed to an alternate table name (or even the name - # of a database view). - # * :readonly - Mark the returned records read-only so they cannot be saved or updated. - # * :lock - An SQL fragment like "FOR UPDATE" or "LOCK IN SHARE MODE". - # :lock => true gives connection's default exclusive lock, usually "FOR UPDATE". - # - # ==== Examples - # - # # find by id - # Person.find(1) # returns the object for ID = 1 - # Person.find(1, 2, 6) # returns an array for objects with IDs in (1, 2, 6) - # Person.find([7, 17]) # returns an array for objects with IDs in (7, 17) - # Person.find([1]) # returns an array for the object with ID = 1 - # Person.find(1, :conditions => "administrator = 1", :order => "created_on DESC") - # - # Note that returned records may not be in the same order as the ids you - # provide since database rows are unordered. Give an explicit :order - # to ensure the results are sorted. - # - # ==== Examples - # - # # find first - # Person.find(:first) # returns the first object fetched by SELECT * FROM people - # Person.find(:first, :conditions => [ "user_name = ?", user_name]) - # Person.find(:first, :conditions => [ "user_name = :u", { :u => user_name }]) - # Person.find(:first, :order => "created_on DESC", :offset => 5) - # - # # find last - # Person.find(:last) # returns the last object fetched by SELECT * FROM people - # Person.find(:last, :conditions => [ "user_name = ?", user_name]) - # Person.find(:last, :order => "created_on DESC", :offset => 5) - # - # # find all - # Person.find(:all) # returns an array of objects for all the rows fetched by SELECT * FROM people - # Person.find(:all, :conditions => [ "category IN (?)", categories], :limit => 50) - # Person.find(:all, :conditions => { :friends => ["Bob", "Steve", "Fred"] } - # Person.find(:all, :offset => 10, :limit => 10) - # Person.find(:all, :include => [ :account, :friends ]) - # Person.find(:all, :group => "category") - # - # Example for find with a lock: Imagine two concurrent transactions: - # each will read person.visits == 2, add 1 to it, and save, resulting - # in two saves of person.visits = 3. By locking the row, the second - # transaction has to wait until the first is finished; we get the - # expected person.visits == 4. - # - # Person.transaction do - # person = Person.find(1, :lock => true) - # person.visits += 1 - # person.save! - # end - def find(*args) - options = args.extract_options! - - relation = construct_finder_arel(options, current_scoped_methods) - - case args.first - when :first, :last, :all - relation.send(args.first) - else - relation.find(*args) - end - end - + delegate :find, :first, :last, :all, :to => :scoped delegate :select, :group, :order, :limit, :joins, :where, :preload, :eager_load, :includes, :from, :lock, :readonly, :having, :to => :scoped delegate :count, :average, :minimum, :maximum, :sum, :calculate, :to => :scoped - # A convenience wrapper for find(:first, *args). You can pass in all the - # same arguments to this method as you can to find(:first). - def first(*args) - find(:first, *args) - end - - # A convenience wrapper for find(:last, *args). You can pass in all the - # same arguments to this method as you can to find(:last). - def last(*args) - find(:last, *args) - end - - # A convenience wrapper for find(:all, *args). You can pass in all the - # same arguments to this method as you can to find(:all). - def all(*args) - find(:all, *args) - end - # Executes a custom SQL query against your database and returns all the results. The results will # be returned as an array with columns requested encapsulated as attributes of the model you call # this method from. If you call Product.find_by_sql then the results will be returned in -- cgit v1.2.3 From 394c05ed82c1fbfc1c5d27f223b49975f439729c Mon Sep 17 00:00:00 2001 From: Pratik Naik Date: Wed, 20 Jan 2010 13:24:37 +0530 Subject: Remove stale methods constructing joins --- activerecord/lib/active_record/base.rb | 28 ---------------------------- 1 file changed, 28 deletions(-) (limited to 'activerecord/lib/active_record/base.rb') diff --git a/activerecord/lib/active_record/base.rb b/activerecord/lib/active_record/base.rb index 6063c9789f..8fcc872113 100755 --- a/activerecord/lib/active_record/base.rb +++ b/activerecord/lib/active_record/base.rb @@ -1455,34 +1455,6 @@ module ActiveRecord #:nodoc: relation end - def construct_join(joins) - case joins - when Symbol, Hash, Array - if array_of_strings?(joins) - joins.join(' ') + " " - else - build_association_joins(joins) - end - when String - " #{joins} " - else - "" - end - end - - def build_association_joins(joins) - join_dependency = ActiveRecord::Associations::ClassMethods::JoinDependency.new(self, joins, nil) - relation = unscoped.table - join_dependency.join_associations.map { |association| - if (association_relation = association.relation).is_a?(Array) - [Arel::InnerJoin.new(relation, association_relation.first, *association.association_join.first).joins(relation), - Arel::InnerJoin.new(relation, association_relation.last, *association.association_join.last).joins(relation)].join() - else - Arel::InnerJoin.new(relation, association_relation, *association.association_join).joins(relation) - end - }.join(" ") - end - def array_of_strings?(o) o.is_a?(Array) && o.all?{|obj| obj.is_a?(String)} end -- cgit v1.2.3 From 5502780c6910fbf6825efa58601d868fca2f1cc1 Mon Sep 17 00:00:00 2001 From: Pratik Naik Date: Wed, 20 Jan 2010 14:01:42 +0530 Subject: Move array_of_strings? to Relation --- activerecord/lib/active_record/base.rb | 4 ---- 1 file changed, 4 deletions(-) (limited to 'activerecord/lib/active_record/base.rb') diff --git a/activerecord/lib/active_record/base.rb b/activerecord/lib/active_record/base.rb index 8fcc872113..8f2ea10206 100755 --- a/activerecord/lib/active_record/base.rb +++ b/activerecord/lib/active_record/base.rb @@ -1455,10 +1455,6 @@ module ActiveRecord #:nodoc: relation end - def array_of_strings?(o) - o.is_a?(Array) && o.all?{|obj| obj.is_a?(String)} - end - def type_condition sti_column = arel_table[inheritance_column] condition = sti_column.eq(sti_name) -- cgit v1.2.3 From 8f0f02a1667d6a1c948d6c60adf9581ec47376b9 Mon Sep 17 00:00:00 2001 From: Pratik Naik Date: Wed, 20 Jan 2010 18:12:50 +0530 Subject: Make Relation#destroy_all handle all the cases --- activerecord/lib/active_record/base.rb | 32 +------------------------------- 1 file changed, 1 insertion(+), 31 deletions(-) (limited to 'activerecord/lib/active_record/base.rb') diff --git a/activerecord/lib/active_record/base.rb b/activerecord/lib/active_record/base.rb index 8f2ea10206..5141f0b32f 100755 --- a/activerecord/lib/active_record/base.rb +++ b/activerecord/lib/active_record/base.rb @@ -556,7 +556,7 @@ module ActiveRecord #:nodoc: end alias :colorize_logging= :colorize_logging - delegate :find, :first, :last, :all, :to => :scoped + delegate :find, :first, :last, :all, :destroy_all, :to => :scoped delegate :select, :group, :order, :limit, :joins, :where, :preload, :eager_load, :includes, :from, :lock, :readonly, :having, :to => :scoped delegate :count, :average, :minimum, :maximum, :sum, :calculate, :to => :scoped @@ -773,36 +773,6 @@ module ActiveRecord #:nodoc: relation.update(sanitize_sql_for_assignment(updates)) end - # Destroys the records matching +conditions+ by instantiating each - # record and calling its +destroy+ method. Each object's callbacks are - # executed (including :dependent association options and - # +before_destroy+/+after_destroy+ Observer methods). Returns the - # collection of objects that were destroyed; each will be frozen, to - # reflect that no changes should be made (since they can't be - # persisted). - # - # Note: Instantiation, callback execution, and deletion of each - # record can be time consuming when you're removing many records at - # once. It generates at least one SQL +DELETE+ query per record (or - # possibly more, to enforce your callbacks). If you want to delete many - # rows quickly, without concern for their associations or callbacks, use - # +delete_all+ instead. - # - # ==== Parameters - # - # * +conditions+ - A string, array, or hash that specifies which records - # to destroy. If omitted, all records are destroyed. See the - # Conditions section in the introduction to ActiveRecord::Base for - # more information. - # - # ==== Examples - # - # Person.destroy_all("last_login < '2004-04-04'") - # Person.destroy_all(:status => "inactive") - def destroy_all(conditions = nil) - where(conditions).destroy_all - end - # Deletes the records matching +conditions+ without instantiating the records first, and hence not # calling the +destroy+ method nor invoking callbacks. This is a single SQL DELETE statement that # goes straight to the database, much more efficient than +destroy_all+. Be careful with relations -- cgit v1.2.3 From 2493229674ba2e8736901d44abe0c82e6ac82993 Mon Sep 17 00:00:00 2001 From: Pratik Naik Date: Wed, 20 Jan 2010 18:17:37 +0530 Subject: Delegate exists? to Relation --- activerecord/lib/active_record/base.rb | 36 +--------------------------------- 1 file changed, 1 insertion(+), 35 deletions(-) (limited to 'activerecord/lib/active_record/base.rb') diff --git a/activerecord/lib/active_record/base.rb b/activerecord/lib/active_record/base.rb index 5141f0b32f..2629abe778 100755 --- a/activerecord/lib/active_record/base.rb +++ b/activerecord/lib/active_record/base.rb @@ -556,7 +556,7 @@ module ActiveRecord #:nodoc: end alias :colorize_logging= :colorize_logging - delegate :find, :first, :last, :all, :destroy_all, :to => :scoped + delegate :find, :first, :last, :all, :destroy_all, :exists?, :to => :scoped delegate :select, :group, :order, :limit, :joins, :where, :preload, :eager_load, :includes, :from, :lock, :readonly, :having, :to => :scoped delegate :count, :average, :minimum, :maximum, :sum, :calculate, :to => :scoped @@ -586,40 +586,6 @@ module ActiveRecord #:nodoc: connection.select_all(sanitize_sql(sql), "#{name} Load").collect! { |record| instantiate(record) } end - # Returns true if a record exists in the table that matches the +id+ or - # conditions given, or false otherwise. The argument can take five forms: - # - # * Integer - Finds the record with this primary key. - # * String - Finds the record with a primary key corresponding to this - # string (such as '5'). - # * Array - Finds the record that matches these +find+-style conditions - # (such as ['color = ?', 'red']). - # * Hash - Finds the record that matches these +find+-style conditions - # (such as {:color => 'red'}). - # * No args - Returns false if the table is empty, true otherwise. - # - # For more information about specifying conditions as a Hash or Array, - # see the Conditions section in the introduction to ActiveRecord::Base. - # - # Note: You can't pass in a condition as a string (like name = - # 'Jamie'), since it would be sanitized and then queried against - # the primary key column, like id = 'name = \'Jamie\''. - # - # ==== Examples - # Person.exists?(5) - # Person.exists?('5') - # Person.exists?(:name => "David") - # Person.exists?(['name LIKE ?', "%#{query}%"]) - # Person.exists? - def exists?(id_or_conditions = nil) - case id_or_conditions - when Array, Hash - where(id_or_conditions).exists? - else - scoped.exists?(id_or_conditions) - end - end - # Creates an object (or multiple objects) and saves it to the database, if validations pass. # The resulting object is returned whether the object was saved successfully to the database or not. # -- cgit v1.2.3 From 223e2a2709cbd0013d51b024bb4e0f950586c125 Mon Sep 17 00:00:00 2001 From: Pratik Naik Date: Wed, 20 Jan 2010 18:24:36 +0530 Subject: Remove Base.delete as it's same as Relation#delete --- activerecord/lib/active_record/base.rb | 26 +------------------------- 1 file changed, 1 insertion(+), 25 deletions(-) (limited to 'activerecord/lib/active_record/base.rb') diff --git a/activerecord/lib/active_record/base.rb b/activerecord/lib/active_record/base.rb index 2629abe778..b79e768d21 100755 --- a/activerecord/lib/active_record/base.rb +++ b/activerecord/lib/active_record/base.rb @@ -556,7 +556,7 @@ module ActiveRecord #:nodoc: end alias :colorize_logging= :colorize_logging - delegate :find, :first, :last, :all, :destroy_all, :exists?, :to => :scoped + delegate :find, :first, :last, :all, :destroy_all, :exists?, :delete, :to => :scoped delegate :select, :group, :order, :limit, :joins, :where, :preload, :eager_load, :includes, :from, :lock, :readonly, :having, :to => :scoped delegate :count, :average, :minimum, :maximum, :sum, :calculate, :to => :scoped @@ -646,30 +646,6 @@ module ActiveRecord #:nodoc: end end - # Deletes the row with a primary key matching the +id+ argument, using a - # SQL +DELETE+ statement, and returns the number of rows deleted. Active - # Record objects are not instantiated, so the object's callbacks are not - # executed, including any :dependent association options or - # Observer methods. - # - # You can delete multiple rows at once by passing an Array of ids. - # - # Note: Although it is often much faster than the alternative, - # #destroy, skipping callbacks might bypass business logic in - # your application that ensures referential integrity or performs other - # essential jobs. - # - # ==== Examples - # - # # Delete a single row - # Todo.delete(1) - # - # # Delete multiple rows - # Todo.delete([2,3,4]) - def delete(id_or_array) - scoped.delete(id_or_array) - end - # Destroy an object (or multiple objects) that has the given id, the object is instantiated first, # therefore all callbacks and filters are fired off before the object is deleted. This method is # less efficient than ActiveRecord#delete but allows cleanup methods and other actions to be run. -- cgit v1.2.3 From 97568056763dc3bca7804a1426fae32a2031cfec Mon Sep 17 00:00:00 2001 From: Pratik Naik Date: Wed, 20 Jan 2010 18:28:45 +0530 Subject: Move destroy to Relation --- activerecord/lib/active_record/base.rb | 29 +---------------------------- 1 file changed, 1 insertion(+), 28 deletions(-) (limited to 'activerecord/lib/active_record/base.rb') diff --git a/activerecord/lib/active_record/base.rb b/activerecord/lib/active_record/base.rb index b79e768d21..6b7faa763b 100755 --- a/activerecord/lib/active_record/base.rb +++ b/activerecord/lib/active_record/base.rb @@ -556,7 +556,7 @@ module ActiveRecord #:nodoc: end alias :colorize_logging= :colorize_logging - delegate :find, :first, :last, :all, :destroy_all, :exists?, :delete, :to => :scoped + delegate :find, :first, :last, :all, :destroy, :destroy_all, :exists?, :delete, :to => :scoped delegate :select, :group, :order, :limit, :joins, :where, :preload, :eager_load, :includes, :from, :lock, :readonly, :having, :to => :scoped delegate :count, :average, :minimum, :maximum, :sum, :calculate, :to => :scoped @@ -646,33 +646,6 @@ module ActiveRecord #:nodoc: end end - # Destroy an object (or multiple objects) that has the given id, the object is instantiated first, - # therefore all callbacks and filters are fired off before the object is deleted. This method is - # less efficient than ActiveRecord#delete but allows cleanup methods and other actions to be run. - # - # This essentially finds the object (or multiple objects) with the given id, creates a new object - # from the attributes, and then calls destroy on it. - # - # ==== Parameters - # - # * +id+ - Can be either an Integer or an Array of Integers. - # - # ==== Examples - # - # # Destroy a single object - # Todo.destroy(1) - # - # # Destroy multiple objects - # todos = [1,2,3] - # Todo.destroy(todos) - def destroy(id) - if id.is_a?(Array) - id.map { |one_id| destroy(one_id) } - else - find(id).destroy - end - end - # Updates all records with details given if they match a set of conditions supplied, limits and order can # also be supplied. This method constructs a single SQL UPDATE statement and sends it straight to the # database. It does not instantiate the involved models and it does not trigger Active Record callbacks -- cgit v1.2.3 From f216fadc0e4a54d1807fe5a9462f7bd34e9024b0 Mon Sep 17 00:00:00 2001 From: Pratik Naik Date: Wed, 20 Jan 2010 18:33:14 +0530 Subject: Delegate delete_all to Relation --- activerecord/lib/active_record/base.rb | 23 +---------------------- 1 file changed, 1 insertion(+), 22 deletions(-) (limited to 'activerecord/lib/active_record/base.rb') diff --git a/activerecord/lib/active_record/base.rb b/activerecord/lib/active_record/base.rb index 6b7faa763b..1896b49977 100755 --- a/activerecord/lib/active_record/base.rb +++ b/activerecord/lib/active_record/base.rb @@ -556,7 +556,7 @@ module ActiveRecord #:nodoc: end alias :colorize_logging= :colorize_logging - delegate :find, :first, :last, :all, :destroy, :destroy_all, :exists?, :delete, :to => :scoped + delegate :find, :first, :last, :all, :destroy, :destroy_all, :exists?, :delete, :delete_all, :to => :scoped delegate :select, :group, :order, :limit, :joins, :where, :preload, :eager_load, :includes, :from, :lock, :readonly, :having, :to => :scoped delegate :count, :average, :minimum, :maximum, :sum, :calculate, :to => :scoped @@ -688,27 +688,6 @@ module ActiveRecord #:nodoc: relation.update(sanitize_sql_for_assignment(updates)) end - # Deletes the records matching +conditions+ without instantiating the records first, and hence not - # calling the +destroy+ method nor invoking callbacks. This is a single SQL DELETE statement that - # goes straight to the database, much more efficient than +destroy_all+. Be careful with relations - # though, in particular :dependent rules defined on associations are not honored. Returns - # the number of rows affected. - # - # ==== Parameters - # - # * +conditions+ - Conditions are specified the same way as with +find+ method. - # - # ==== Example - # - # Post.delete_all("person_id = 5 AND (category = 'Something' OR category = 'Else')") - # Post.delete_all(["person_id = ? AND (category = ? OR category = ?)", 5, 'Something', 'Else']) - # - # Both calls delete the affected posts all at once with a single DELETE statement. If you need to destroy dependent - # associations or call your before_* or +after_destroy+ callbacks, use the +destroy_all+ method instead. - def delete_all(conditions = nil) - where(conditions).delete_all - end - # Returns the result of an SQL statement that should only include a COUNT(*) in the SELECT part. # The use of this method should be restricted to complicated SQL queries that can't be executed # using the ActiveRecord::Calculations class methods. Look into those before using this. -- cgit v1.2.3 From 8b9bfbe225a59ccefa46f1e8bf301bc483bef0e0 Mon Sep 17 00:00:00 2001 From: Pratik Naik Date: Wed, 20 Jan 2010 18:40:19 +0530 Subject: Dont delegate Relation#update to arel --- activerecord/lib/active_record/base.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'activerecord/lib/active_record/base.rb') diff --git a/activerecord/lib/active_record/base.rb b/activerecord/lib/active_record/base.rb index 1896b49977..45edc3fe60 100755 --- a/activerecord/lib/active_record/base.rb +++ b/activerecord/lib/active_record/base.rb @@ -685,7 +685,7 @@ module ActiveRecord #:nodoc: relation = current_scoped_methods.except(:limit, :order).merge(relation) if current_scoped_methods end - relation.update(sanitize_sql_for_assignment(updates)) + relation.arel.update(sanitize_sql_for_assignment(updates)) end # Returns the result of an SQL statement that should only include a COUNT(*) in the SELECT part. @@ -2188,7 +2188,7 @@ module ActiveRecord #:nodoc: def update(attribute_names = @attributes.keys) attributes_with_values = arel_attributes_values(false, false, attribute_names) return 0 if attributes_with_values.empty? - self.class.unscoped.where(self.class.arel_table[self.class.primary_key].eq(id)).update(attributes_with_values) + self.class.unscoped.where(self.class.arel_table[self.class.primary_key].eq(id)).arel.update(attributes_with_values) end # Creates a record with values matching those of the instance attributes -- cgit v1.2.3 From 1fb78e3ed8142782f19877a195f10b1828dd672c Mon Sep 17 00:00:00 2001 From: Pratik Naik Date: Wed, 20 Jan 2010 20:37:03 +0530 Subject: Base.merge_conditions is no longer needed --- activerecord/lib/active_record/base.rb | 14 -------------- 1 file changed, 14 deletions(-) (limited to 'activerecord/lib/active_record/base.rb') diff --git a/activerecord/lib/active_record/base.rb b/activerecord/lib/active_record/base.rb index 45edc3fe60..f71ccb3a51 100755 --- a/activerecord/lib/active_record/base.rb +++ b/activerecord/lib/active_record/base.rb @@ -1238,20 +1238,6 @@ module ActiveRecord #:nodoc: store_full_sti_class ? name : name.demodulize end - # Merges conditions so that the result is a valid +condition+ - def merge_conditions(*conditions) - segments = [] - - conditions.each do |condition| - unless condition.blank? - sql = sanitize_sql(condition) - segments << sql unless sql.blank? - end - end - - "(#{segments.join(') AND (')})" unless segments.empty? - end - def unscoped @unscoped ||= Relation.new(self, arel_table) finder_needs_type_condition? ? @unscoped.where(type_condition) : @unscoped -- cgit v1.2.3 From 8d31c9f3a0c69ce7e8f905a4e75177037bbbcad5 Mon Sep 17 00:00:00 2001 From: Pratik Naik Date: Wed, 20 Jan 2010 22:20:08 +0530 Subject: Move update and update_all to Relation --- activerecord/lib/active_record/base.rb | 71 +--------------------------------- 1 file changed, 1 insertion(+), 70 deletions(-) (limited to 'activerecord/lib/active_record/base.rb') diff --git a/activerecord/lib/active_record/base.rb b/activerecord/lib/active_record/base.rb index f71ccb3a51..79ec171861 100755 --- a/activerecord/lib/active_record/base.rb +++ b/activerecord/lib/active_record/base.rb @@ -556,7 +556,7 @@ module ActiveRecord #:nodoc: end alias :colorize_logging= :colorize_logging - delegate :find, :first, :last, :all, :destroy, :destroy_all, :exists?, :delete, :delete_all, :to => :scoped + delegate :find, :first, :last, :all, :destroy, :destroy_all, :exists?, :delete, :delete_all, :update, :update_all, :to => :scoped delegate :select, :group, :order, :limit, :joins, :where, :preload, :eager_load, :includes, :from, :lock, :readonly, :having, :to => :scoped delegate :count, :average, :minimum, :maximum, :sum, :calculate, :to => :scoped @@ -619,75 +619,6 @@ module ActiveRecord #:nodoc: end end - # Updates an object (or multiple objects) and saves it to the database, if validations pass. - # The resulting object is returned whether the object was saved successfully to the database or not. - # - # ==== Parameters - # - # * +id+ - This should be the id or an array of ids to be updated. - # * +attributes+ - This should be a hash of attributes to be set on the object, or an array of hashes. - # - # ==== Examples - # - # # Updating one record: - # Person.update(15, :user_name => 'Samuel', :group => 'expert') - # - # # Updating multiple records: - # people = { 1 => { "first_name" => "David" }, 2 => { "first_name" => "Jeremy" } } - # Person.update(people.keys, people.values) - def update(id, attributes) - if id.is_a?(Array) - idx = -1 - id.collect { |one_id| idx += 1; update(one_id, attributes[idx]) } - else - object = find(id) - object.update_attributes(attributes) - object - end - end - - # Updates all records with details given if they match a set of conditions supplied, limits and order can - # also be supplied. This method constructs a single SQL UPDATE statement and sends it straight to the - # database. It does not instantiate the involved models and it does not trigger Active Record callbacks - # or validations. - # - # ==== Parameters - # - # * +updates+ - A string, array, or hash representing the SET part of an SQL statement. - # * +conditions+ - A string, array, or hash representing the WHERE part of an SQL statement. See conditions in the intro. - # * +options+ - Additional options are :limit and :order, see the examples for usage. - # - # ==== Examples - # - # # Update all customers with the given attributes - # Customer.update_all :wants_email => true - # - # # Update all books with 'Rails' in their title - # Book.update_all "author = 'David'", "title LIKE '%Rails%'" - # - # # Update all avatars migrated more than a week ago - # Avatar.update_all ['migrated_at = ?', Time.now.utc], ['migrated_at > ?', 1.week.ago] - # - # # Update all books that match our conditions, but limit it to 5 ordered by date - # Book.update_all "author = 'David'", "title LIKE '%Rails%'", :order => 'created_at', :limit => 5 - def update_all(updates, conditions = nil, options = {}) - relation = unscoped - - relation = relation.where(conditions) if conditions - relation = relation.limit(options[:limit]) if options[:limit].present? - relation = relation.order(options[:order]) if options[:order].present? - - if current_scoped_methods && current_scoped_methods.limit_value.present? && current_scoped_methods.order_values.present? - # Only take order from scope if limit is also provided by scope, this - # is useful for updating a has_many association with a limit. - relation = current_scoped_methods.merge(relation) if current_scoped_methods - else - relation = current_scoped_methods.except(:limit, :order).merge(relation) if current_scoped_methods - end - - relation.arel.update(sanitize_sql_for_assignment(updates)) - end - # Returns the result of an SQL statement that should only include a COUNT(*) in the SELECT part. # The use of this method should be restricted to complicated SQL queries that can't be executed # using the ActiveRecord::Calculations class methods. Look into those before using this. -- cgit v1.2.3 From 798d2828dc28a596a9980a149a2d1210f32078d9 Mon Sep 17 00:00:00 2001 From: Pratik Naik Date: Thu, 21 Jan 2010 01:28:50 +0530 Subject: Cache quoted_table_name --- activerecord/lib/active_record/base.rb | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) (limited to 'activerecord/lib/active_record/base.rb') diff --git a/activerecord/lib/active_record/base.rb b/activerecord/lib/active_record/base.rb index 79ec171861..bc1b0bde31 100755 --- a/activerecord/lib/active_record/base.rb +++ b/activerecord/lib/active_record/base.rb @@ -906,6 +906,10 @@ module ActiveRecord #:nodoc: reset_table_name end + def quoted_table_name + @quoted_table_name ||= connection.quote_table_name(table_name) + end + def reset_table_name #:nodoc: base = base_class @@ -923,6 +927,7 @@ module ActiveRecord #:nodoc: name = "#{table_name_prefix}#{contained}#{undecorated_table_name(base.name)}#{table_name_suffix}" end + @quoted_table_name = nil set_table_name(name) name end @@ -2329,10 +2334,6 @@ module ActiveRecord #:nodoc: hash.inject([]) { |list, pair| list << "#{pair.first} = #{pair.last}" }.join(", ") end - def self.quoted_table_name - self.connection.quote_table_name(self.table_name) - end - def quote_columns(quoter, hash) hash.inject({}) do |quoted, (name, value)| quoted[quoter.quote_column_name(name)] = value -- cgit v1.2.3 From 6d30002a52133bd105adb29084f4cc72b1ee847f Mon Sep 17 00:00:00 2001 From: Pratik Naik Date: Fri, 22 Jan 2010 00:51:45 +0530 Subject: Revert "Refactoring attributes/types" [#3348 state:open] This reverts commit f936a1f100e75082081e782e5cceb272885c2df7. Conflicts: activerecord/lib/active_record.rb activerecord/lib/active_record/base.rb Revert "Fixed: #without_typecast should only disable typecasting on the duplicated attributes" [#3387 state:open] This reverts commit 2831996483c6a045f1f38d8030256eb58d9771c3. Reason : It's not generating attribute methods properly, making object.column 5x slower. --- activerecord/lib/active_record/base.rb | 37 ++++++++++++++++++++++++++++------ 1 file changed, 31 insertions(+), 6 deletions(-) (limited to 'activerecord/lib/active_record/base.rb') diff --git a/activerecord/lib/active_record/base.rb b/activerecord/lib/active_record/base.rb index bc1b0bde31..f1b2b3b979 100755 --- a/activerecord/lib/active_record/base.rb +++ b/activerecord/lib/active_record/base.rb @@ -1200,7 +1200,7 @@ module ActiveRecord #:nodoc: def instantiate(record) object = find_sti_class(record[inheritance_column]).allocate - object.send(:initialize_attribute_store, record) + object.instance_variable_set(:'@attributes', record) object.instance_variable_set(:'@attributes_cache', {}) object.send(:_run_find_callbacks) @@ -1663,7 +1663,7 @@ module ActiveRecord #:nodoc: # In both instances, valid attribute keys are determined by the column names of the associated table -- # hence you can't have attributes that aren't part of the table columns. def initialize(attributes = nil) - initialize_attribute_store(attributes_from_column_definition) + @attributes = attributes_from_column_definition @attributes_cache = {} @new_record = true ensure_proper_type @@ -1694,7 +1694,7 @@ module ActiveRecord #:nodoc: callback(:after_initialize) if respond_to_without_attributes?(:after_initialize) cloned_attributes = other.clone_attributes(:read_attribute_before_type_cast) cloned_attributes.delete(self.class.primary_key) - initialize_attribute_store(cloned_attributes) + @attributes = cloned_attributes clear_aggregation_cache @attributes_cache = {} @new_record = true @@ -1924,11 +1924,21 @@ module ActiveRecord #:nodoc: def reload(options = nil) clear_aggregation_cache clear_association_cache - _attributes.update(self.class.find(self.id, options).instance_variable_get('@attributes')) + @attributes.update(self.class.find(self.id, options).instance_variable_get('@attributes')) @attributes_cache = {} self end + # Returns true if the given attribute is in the attributes hash + def has_attribute?(attr_name) + @attributes.has_key?(attr_name.to_s) + end + + # Returns an array of names for the attributes available on this object sorted alphabetically. + def attribute_names + @attributes.keys.sort + end + # Returns the value of the attribute identified by attr_name after it has been typecast (for example, # "2004-12-12" in a data column is cast to a date object, like Date.new(2004, 12, 12)). # (Alias for the protected read_attribute method). @@ -2262,7 +2272,7 @@ module ActiveRecord #:nodoc: end def instantiate_time_object(name, values) - if self.class.send(:time_zone_aware?, name) + if self.class.send(:create_time_zone_conversion_attribute?, name, column_for_attribute(name)) Time.zone.local(*values) else Time.time_with_datetime_fallback(@@default_timezone, *values) @@ -2345,6 +2355,22 @@ module ActiveRecord #:nodoc: comma_pair_list(quote_columns(quoter, hash)) end + def convert_number_column_value(value) + if value == false + 0 + elsif value == true + 1 + elsif value.is_a?(String) && value.blank? + nil + else + value + end + end + + def object_from_yaml(string) + return string unless string.is_a?(String) && string =~ /^---/ + YAML::load(string) rescue string + end end Base.class_eval do @@ -2359,7 +2385,6 @@ module ActiveRecord #:nodoc: include AttributeMethods::PrimaryKey include AttributeMethods::TimeZoneConversion include AttributeMethods::Dirty - include Attributes, Types include Callbacks, ActiveModel::Observing, Timestamp include Associations, AssociationPreload, NamedScope include ActiveModel::Conversion -- cgit v1.2.3 From 8ff2fb6f3aa6140f5a8bd018d5919a8a1e707cda Mon Sep 17 00:00:00 2001 From: Pratik Naik Date: Sat, 23 Jan 2010 13:40:38 +0530 Subject: Make default_scope work with Relations --- activerecord/lib/active_record/base.rb | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'activerecord/lib/active_record/base.rb') diff --git a/activerecord/lib/active_record/base.rb b/activerecord/lib/active_record/base.rb index f1b2b3b979..12feef4849 100755 --- a/activerecord/lib/active_record/base.rb +++ b/activerecord/lib/active_record/base.rb @@ -1236,7 +1236,7 @@ module ActiveRecord #:nodoc: end def construct_finder_arel(options = {}, scope = nil) - relation = unscoped.apply_finder_options(options) + relation = options.is_a?(Hash) ? unscoped.apply_finder_options(options) : unscoped.merge(options) relation = scope.merge(relation) if scope relation end @@ -1450,7 +1450,8 @@ module ActiveRecord #:nodoc: end def scoped_methods #:nodoc: - Thread.current[:"#{self}_scoped_methods"] ||= self.default_scoping.dup + key = :"#{self}_scoped_methods" + Thread.current[key] = Thread.current[key].presence || self.default_scoping.dup end def current_scoped_methods #:nodoc: -- cgit v1.2.3