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 +------------------------- activerecord/lib/active_record/relation.rb | 36 +++++++++++++++++++++++++++--- 2 files changed, 34 insertions(+), 34 deletions(-) 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 diff --git a/activerecord/lib/active_record/relation.rb b/activerecord/lib/active_record/relation.rb index decde50427..8942690b49 100644 --- a/activerecord/lib/active_record/relation.rb +++ b/activerecord/lib/active_record/relation.rb @@ -84,9 +84,39 @@ module ActiveRecord end end - def destroy_all - to_a.each {|object| object.destroy} - reset + # 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) + if conditions + where(conditions).destroy_all + else + to_a.each {|object| object.destroy} + reset + end end def delete_all -- 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 +--------------------- .../lib/active_record/relation/finder_methods.rb | 36 ++++++++++++++++++++-- 2 files changed, 34 insertions(+), 38 deletions(-) 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. # diff --git a/activerecord/lib/active_record/relation/finder_methods.rb b/activerecord/lib/active_record/relation/finder_methods.rb index 999309d2bd..2e451e380b 100644 --- a/activerecord/lib/active_record/relation/finder_methods.rb +++ b/activerecord/lib/active_record/relation/finder_methods.rb @@ -119,10 +119,40 @@ module ActiveRecord args.any? ? apply_finder_options(args.first).to_a : to_a 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 = nil) - relation = select(primary_key).limit(1) - relation = relation.where(primary_key.eq(id)) if id - relation.first ? true : false + case id + when Array, Hash + where(id).exists? + else + relation = select(primary_key).limit(1) + relation = relation.where(primary_key.eq(id)) if id + relation.first ? true : false + end end protected -- 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 +------------------------- activerecord/lib/active_record/relation.rb | 20 ++++++++++++++++++++ 2 files changed, 21 insertions(+), 25 deletions(-) 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. diff --git a/activerecord/lib/active_record/relation.rb b/activerecord/lib/active_record/relation.rb index 8942690b49..217fbb2ff4 100644 --- a/activerecord/lib/active_record/relation.rb +++ b/activerecord/lib/active_record/relation.rb @@ -123,6 +123,26 @@ module ActiveRecord arel.delete.tap { reset } 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) where(@klass.primary_key => id_or_array).delete_all end -- 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 +---------------------------- activerecord/lib/active_record/relation.rb | 27 +++++++++++++++++++++++++++ 2 files changed, 28 insertions(+), 28 deletions(-) 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 diff --git a/activerecord/lib/active_record/relation.rb b/activerecord/lib/active_record/relation.rb index 217fbb2ff4..a253dbd19d 100644 --- a/activerecord/lib/active_record/relation.rb +++ b/activerecord/lib/active_record/relation.rb @@ -119,6 +119,33 @@ module ActiveRecord 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 + def delete_all arel.delete.tap { reset } end -- 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 +---------------------- activerecord/lib/active_record/relation.rb | 21 +++++++++++++++++++-- 2 files changed, 20 insertions(+), 24 deletions(-) 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. diff --git a/activerecord/lib/active_record/relation.rb b/activerecord/lib/active_record/relation.rb index a253dbd19d..a6c283e03c 100644 --- a/activerecord/lib/active_record/relation.rb +++ b/activerecord/lib/active_record/relation.rb @@ -146,8 +146,25 @@ module ActiveRecord end end - def delete_all - arel.delete.tap { reset } + # 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) + conditions ? where(conditions).delete_all : arel.delete.tap { reset } end # Deletes the row with a primary key matching the +id+ argument, using a -- 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 ++-- activerecord/lib/active_record/locking/optimistic.rb | 2 +- activerecord/lib/active_record/relation.rb | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) 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 diff --git a/activerecord/lib/active_record/locking/optimistic.rb b/activerecord/lib/active_record/locking/optimistic.rb index bf0683eb8f..9044ca418b 100644 --- a/activerecord/lib/active_record/locking/optimistic.rb +++ b/activerecord/lib/active_record/locking/optimistic.rb @@ -84,7 +84,7 @@ module ActiveRecord relation.table[self.class.primary_key].eq(quoted_id).and( relation.table[self.class.locking_column].eq(quote_value(previous_value)) ) - ).update(arel_attributes_values(false, false, attribute_names)) + ).arel.update(arel_attributes_values(false, false, attribute_names)) unless affected_rows == 1 diff --git a/activerecord/lib/active_record/relation.rb b/activerecord/lib/active_record/relation.rb index a6c283e03c..a7750f60b4 100644 --- a/activerecord/lib/active_record/relation.rb +++ b/activerecord/lib/active_record/relation.rb @@ -8,7 +8,7 @@ module ActiveRecord include FinderMethods, Calculations, SpawnMethods, QueryMethods delegate :length, :collect, :map, :each, :all?, :include?, :to => :to_a - delegate :insert, :update, :to => :arel + delegate :insert, :to => :arel attr_reader :table, :klass -- cgit v1.2.3 From 8e2fd54b19656a6edbd94f8707927d09e167e7fc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Valim?= Date: Wed, 20 Jan 2010 14:21:27 +0100 Subject: Bring normalize behavior to AbstractController::Rendering --- .../lib/abstract_controller/localized_cache.rb | 2 +- actionpack/lib/abstract_controller/rendering.rb | 22 +++++++++++++--- actionpack/lib/action_controller/base.rb | 29 ++++++---------------- .../lib/action_controller/metal/instrumentation.rb | 16 ++++-------- .../lib/action_controller/metal/rendering.rb | 7 +++--- 5 files changed, 37 insertions(+), 39 deletions(-) diff --git a/actionpack/lib/abstract_controller/localized_cache.rb b/actionpack/lib/abstract_controller/localized_cache.rb index bf648af60a..5e3efa002c 100644 --- a/actionpack/lib/abstract_controller/localized_cache.rb +++ b/actionpack/lib/abstract_controller/localized_cache.rb @@ -34,7 +34,7 @@ module AbstractController end end - def render(options) + def render(*args) Thread.current[:format_locale_key] = HashKey.get(self.class, formats, I18n.locale) super end diff --git a/actionpack/lib/abstract_controller/rendering.rb b/actionpack/lib/abstract_controller/rendering.rb index 0dab4a3cc0..644419a585 100644 --- a/actionpack/lib/abstract_controller/rendering.rb +++ b/actionpack/lib/abstract_controller/rendering.rb @@ -40,12 +40,13 @@ module AbstractController # Mostly abstracts the fact that calling render twice is a DoubleRenderError. # Delegates render_to_body and sticks the result in self.response_body. - def render(*args) + def render(*args, &block) if response_body raise AbstractController::DoubleRenderError, "Can only render or redirect once per action" end - self.response_body = render_to_body(*args) + options = _normalize_options(*args, &block) + self.response_body = render_to_body(options) end # Raw rendering of a template to a Rack-compatible body. @@ -69,7 +70,8 @@ module AbstractController # render_to_body into a String. # # :api: plugin - def render_to_string(options = {}) + def render_to_string(*args) + options = _normalize_options(*args) AbstractController::Rendering.body_to_s(render_to_body(options)) end @@ -96,6 +98,20 @@ module AbstractController _view_paths end + # Normalize options, by converting render "foo" to render :template => "foo" + # and render "/foo" to render :file => "/foo". + def _normalize_options(action=nil, options={}) + case action + when Hash + options, action = action, nil + when String + key = (action.index("/") == 0 ? :file : :template) + options.merge!(key => action) + end + + options + end + # Return a string representation of a Rack-compatible response body. def self.body_to_s(body) if body.respond_to?(:to_str) diff --git a/actionpack/lib/action_controller/base.rb b/actionpack/lib/action_controller/base.rb index f86a61d791..4f928e37ea 100644 --- a/actionpack/lib/action_controller/base.rb +++ b/actionpack/lib/action_controller/base.rb @@ -74,17 +74,14 @@ module ActionController @subclasses ||= [] end - def _normalize_options(action = nil, options = {}, &blk) - if action.is_a?(Hash) - options, action = action, nil - elsif action.is_a?(String) || action.is_a?(Symbol) - key = case action = action.to_s - when %r{^/} then :file - when %r{/} then :template - else :action - end - options.merge! key => action - elsif action + def _normalize_options(action=nil, options={}, &blk) + case action + when NilClass + when Hash, String + options = super + when Symbol + options.merge! :action => action + else options.merge! :partial => action end @@ -99,15 +96,5 @@ module ActionController options[:update] = blk if block_given? options end - - def render(action = nil, options = {}, &blk) - options = _normalize_options(action, options, &blk) - super(options) - end - - def render_to_string(action = nil, options = {}, &blk) - options = _normalize_options(action, options, &blk) - super(options) - end end end diff --git a/actionpack/lib/action_controller/metal/instrumentation.rb b/actionpack/lib/action_controller/metal/instrumentation.rb index 7b2b037c67..19c962bafa 100644 --- a/actionpack/lib/action_controller/metal/instrumentation.rb +++ b/actionpack/lib/action_controller/metal/instrumentation.rb @@ -32,18 +32,12 @@ module ActionController end end - def render(*args, &block) - if logger - render_output = nil - - self.view_runtime = cleanup_view_runtime do - Benchmark.ms { render_output = super } - end - - render_output - else - super + def render(*args) + render_output = nil + self.view_runtime = cleanup_view_runtime do + Benchmark.ms { render_output = super } end + render_output end def send_file(path, options={}) diff --git a/actionpack/lib/action_controller/metal/rendering.rb b/actionpack/lib/action_controller/metal/rendering.rb index 74e50bb032..475ed54167 100644 --- a/actionpack/lib/action_controller/metal/rendering.rb +++ b/actionpack/lib/action_controller/metal/rendering.rb @@ -12,9 +12,10 @@ module ActionController super end - def render(options) - super - self.content_type ||= options[:_template].mime_type.to_s + def render(*args) + args << {} unless args.last.is_a?(Hash) + super(*args) + self.content_type ||= args.last[:_template].mime_type.to_s response_body end -- cgit v1.2.3 From 6e26be69606c52dbccfad366661b455157c35be4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Valim?= Date: Wed, 20 Jan 2010 14:41:23 +0100 Subject: Move ActionController::Translation to AbstractController::Translation. --- actionpack/lib/abstract_controller.rb | 1 + actionpack/lib/abstract_controller/rendering.rb | 2 +- actionpack/lib/abstract_controller/translation.rb | 13 ++++++++++++ actionpack/lib/action_controller.rb | 1 - actionpack/lib/action_controller/base.rb | 2 +- actionpack/lib/action_controller/translation.rb | 13 ------------ actionpack/test/abstract/translation_test.rb | 26 +++++++++++++++++++++++ actionpack/test/controller/translation_test.rb | 26 ----------------------- 8 files changed, 42 insertions(+), 42 deletions(-) create mode 100644 actionpack/lib/abstract_controller/translation.rb delete mode 100644 actionpack/lib/action_controller/translation.rb create mode 100644 actionpack/test/abstract/translation_test.rb delete mode 100644 actionpack/test/controller/translation_test.rb diff --git a/actionpack/lib/abstract_controller.rb b/actionpack/lib/abstract_controller.rb index efc35a7e56..725d8fb8fc 100644 --- a/actionpack/lib/abstract_controller.rb +++ b/actionpack/lib/abstract_controller.rb @@ -15,5 +15,6 @@ module AbstractController autoload :LocalizedCache autoload :Logger autoload :Rendering + autoload :Translation autoload :UrlFor end diff --git a/actionpack/lib/abstract_controller/rendering.rb b/actionpack/lib/abstract_controller/rendering.rb index 644419a585..826e82c8c6 100644 --- a/actionpack/lib/abstract_controller/rendering.rb +++ b/actionpack/lib/abstract_controller/rendering.rb @@ -42,7 +42,7 @@ module AbstractController # Delegates render_to_body and sticks the result in self.response_body. def render(*args, &block) if response_body - raise AbstractController::DoubleRenderError, "Can only render or redirect once per action" + raise AbstractController::DoubleRenderError end options = _normalize_options(*args, &block) diff --git a/actionpack/lib/abstract_controller/translation.rb b/actionpack/lib/abstract_controller/translation.rb new file mode 100644 index 0000000000..6d68cf4944 --- /dev/null +++ b/actionpack/lib/abstract_controller/translation.rb @@ -0,0 +1,13 @@ +module AbstractController + module Translation + def translate(*args) + I18n.translate(*args) + end + alias :t :translate + + def localize(*args) + I18n.localize(*args) + end + alias :l :localize + end +end \ No newline at end of file diff --git a/actionpack/lib/action_controller.rb b/actionpack/lib/action_controller.rb index 8bc2cc79d2..fa4a253ec1 100644 --- a/actionpack/lib/action_controller.rb +++ b/actionpack/lib/action_controller.rb @@ -8,7 +8,6 @@ module ActionController autoload :Base autoload :Caching autoload :PolymorphicRoutes - autoload :Translation autoload :Metal autoload :Middleware diff --git a/actionpack/lib/action_controller/base.rb b/actionpack/lib/action_controller/base.rb index 4f928e37ea..21a811c004 100644 --- a/actionpack/lib/action_controller/base.rb +++ b/actionpack/lib/action_controller/base.rb @@ -4,6 +4,7 @@ module ActionController include AbstractController::Callbacks include AbstractController::Layouts + include AbstractController::Translation include ActionController::Helpers helper :all # By default, all helpers should be included @@ -33,7 +34,6 @@ module ActionController include ActionController::Streaming include ActionController::HttpAuthentication::Basic::ControllerMethods include ActionController::HttpAuthentication::Digest::ControllerMethods - include ActionController::Translation # Add instrumentations hooks at the bottom, to ensure they instrument # all the methods properly. diff --git a/actionpack/lib/action_controller/translation.rb b/actionpack/lib/action_controller/translation.rb deleted file mode 100644 index 65e9eddb0a..0000000000 --- a/actionpack/lib/action_controller/translation.rb +++ /dev/null @@ -1,13 +0,0 @@ -module ActionController - module Translation - def translate(*args) - I18n.translate(*args) - end - alias :t :translate - - def localize(*args) - I18n.localize(*args) - end - alias :l :localize - end -end \ No newline at end of file diff --git a/actionpack/test/abstract/translation_test.rb b/actionpack/test/abstract/translation_test.rb new file mode 100644 index 0000000000..0bf61a6556 --- /dev/null +++ b/actionpack/test/abstract/translation_test.rb @@ -0,0 +1,26 @@ +require 'abstract_unit' + +# class TranslatingController < ActionController::Base +# end + +class TranslationControllerTest < Test::Unit::TestCase + def setup + @controller = ActionController::Base.new + end + + def test_action_controller_base_responds_to_translate + assert @controller.respond_to?(:translate) + end + + def test_action_controller_base_responds_to_t + assert @controller.respond_to?(:t) + end + + def test_action_controller_base_responds_to_localize + assert @controller.respond_to?(:localize) + end + + def test_action_controller_base_responds_to_l + assert @controller.respond_to?(:l) + end +end \ No newline at end of file diff --git a/actionpack/test/controller/translation_test.rb b/actionpack/test/controller/translation_test.rb deleted file mode 100644 index 0bf61a6556..0000000000 --- a/actionpack/test/controller/translation_test.rb +++ /dev/null @@ -1,26 +0,0 @@ -require 'abstract_unit' - -# class TranslatingController < ActionController::Base -# end - -class TranslationControllerTest < Test::Unit::TestCase - def setup - @controller = ActionController::Base.new - end - - def test_action_controller_base_responds_to_translate - assert @controller.respond_to?(:translate) - end - - def test_action_controller_base_responds_to_t - assert @controller.respond_to?(:t) - end - - def test_action_controller_base_responds_to_localize - assert @controller.respond_to?(:localize) - end - - def test_action_controller_base_responds_to_l - assert @controller.respond_to?(:l) - end -end \ No newline at end of file -- cgit v1.2.3 From d1ffc54c06fbacf46783f5ebc84bc125c9188fd1 Mon Sep 17 00:00:00 2001 From: Santiago Pastorino Date: Sun, 17 Jan 2010 04:21:35 -0200 Subject: fixes the failure of config.plugins without :all option tests [#3718 status:resolved] MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: José Valim --- railties/lib/rails/application.rb | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/railties/lib/rails/application.rb b/railties/lib/rails/application.rb index b92a7ff129..743681359c 100644 --- a/railties/lib/rails/application.rb +++ b/railties/lib/rails/application.rb @@ -93,13 +93,12 @@ module Rails initializers end - # TODO: Fix this method + # TODO: Fix this method. It loads all railties independent if :all is given + # or not, otherwise frameworks are never loaded. def plugins @plugins ||= begin plugin_names = (config.plugins || [:all]).map { |p| p.to_sym } - Railtie.plugins.select { |p| - plugin_names.include?(:all) || plugin_names.include?(p.plugin_name) - }.map { |p| p.new } + Plugin.all(plugin_names, config.paths.vendor.plugins) + Railtie.plugins.map(&:new) + Plugin.all(plugin_names, config.paths.vendor.plugins) end end -- cgit v1.2.3 From 909443eab67c4f07aeb6a294e3858792f075b3ab Mon Sep 17 00:00:00 2001 From: Joshua Peek Date: Wed, 20 Jan 2010 08:59:26 -0600 Subject: Expose last controller in rack env["action_controller.instance"] --- actionpack/lib/action_controller/metal.rb | 1 + .../lib/action_dispatch/testing/integration.rb | 38 ++++------------------ 2 files changed, 7 insertions(+), 32 deletions(-) diff --git a/actionpack/lib/action_controller/metal.rb b/actionpack/lib/action_controller/metal.rb index 1819c0f886..57627a6f0b 100644 --- a/actionpack/lib/action_controller/metal.rb +++ b/actionpack/lib/action_controller/metal.rb @@ -60,6 +60,7 @@ module ActionController # :api: private def dispatch(name, env) @_env = env + @_env['action_controller.instance'] = self process(name) to_a end diff --git a/actionpack/lib/action_dispatch/testing/integration.rb b/actionpack/lib/action_dispatch/testing/integration.rb index d4c9df7ebd..2093bb3a0e 100644 --- a/actionpack/lib/action_dispatch/testing/integration.rb +++ b/actionpack/lib/action_dispatch/testing/integration.rb @@ -240,9 +240,9 @@ module ActionDispatch path = location.query ? "#{location.path}?#{location.query}" : location.path end - [ControllerCapture, ActionController::Testing].each do |mod| - unless ActionController::Base < mod - ActionController::Base.class_eval { include mod } + unless ActionController::Base < ActionController::Testing + ActionController::Base.class_eval do + include ActionController::Testing end end @@ -269,16 +269,15 @@ module ActionDispatch end session = Rack::Test::Session.new(@mock_session) - - @controller = ActionController::Base.capture_instantiation do - session.request(path, env) - end + session.request(path, env) @request_count += 1 @request = ActionDispatch::Request.new(session.last_request.env) @response = ActionDispatch::TestResponse.from_response(@mock_session.last_response) @html_document = nil + @controller = session.last_request.env['action_controller.instance'] + return response.status end @@ -296,31 +295,6 @@ module ActionDispatch end end - # A module used to extend ActionController::Base, so that integration tests - # can capture the controller used to satisfy a request. - module ControllerCapture #:nodoc: - extend ActiveSupport::Concern - - included do - alias_method_chain :initialize, :capture - end - - def initialize_with_capture(*args) - initialize_without_capture - self.class.last_instantiation ||= self - end - - module ClassMethods #:nodoc: - mattr_accessor :last_instantiation - - def capture_instantiation - self.last_instantiation = nil - yield - return last_instantiation - end - end - end - module Runner def app @app -- 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 -------------- activerecord/lib/active_record/relation/query_methods.rb | 4 ++-- 2 files changed, 2 insertions(+), 16 deletions(-) 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 diff --git a/activerecord/lib/active_record/relation/query_methods.rb b/activerecord/lib/active_record/relation/query_methods.rb index 163d698b5c..bad6fd716b 100644 --- a/activerecord/lib/active_record/relation/query_methods.rb +++ b/activerecord/lib/active_record/relation/query_methods.rb @@ -167,8 +167,8 @@ module ActiveRecord builder = PredicateBuilder.new(table.engine) conditions = if [String, Array].include?(args.first.class) - merged = @klass.send(:merge_conditions, args.size > 1 ? Array.wrap(args) : args.first) - Arel::SqlLiteral.new(merged) if merged + sql = @klass.send(:sanitize_sql, args.size > 1 ? args : args.first) + Arel::SqlLiteral.new("(#{sql})") if sql.present? elsif args.first.is_a?(Hash) attributes = @klass.send(:expand_hash_conditions_for_aggregates, args.first) builder.build_from_hash(attributes, table) -- cgit v1.2.3 From f7d94cdc6d01617ff4579fda6a56a3e94be47ffe Mon Sep 17 00:00:00 2001 From: Pratik Naik Date: Wed, 20 Jan 2010 20:40:20 +0530 Subject: Fix AP's AR integration tests warning --- activerecord/lib/active_record/named_scope.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/activerecord/lib/active_record/named_scope.rb b/activerecord/lib/active_record/named_scope.rb index d606934dce..ff6c041ef4 100644 --- a/activerecord/lib/active_record/named_scope.rb +++ b/activerecord/lib/active_record/named_scope.rb @@ -165,7 +165,7 @@ module ActiveRecord end def ==(other) - other.respond_to?(:to_a) ? to_a == other.to_a : false + other.respond_to?(:to_ary) ? to_a == other.to_a : false end private -- cgit v1.2.3 From 87bcf1aa15f8edb4287e1916b65a2c523f765e86 Mon Sep 17 00:00:00 2001 From: Joshua Peek Date: Wed, 20 Jan 2010 09:55:33 -0600 Subject: Request#filter_parameters and filter_env --- actionpack/lib/action_dispatch/http/parameters.rb | 26 +++++++++++++++++++++-- 1 file changed, 24 insertions(+), 2 deletions(-) diff --git a/actionpack/lib/action_dispatch/http/parameters.rb b/actionpack/lib/action_dispatch/http/parameters.rb index 97546d5f93..68ba3637bf 100644 --- a/actionpack/lib/action_dispatch/http/parameters.rb +++ b/actionpack/lib/action_dispatch/http/parameters.rb @@ -29,9 +29,31 @@ module ActionDispatch def path_parameters @env["action_dispatch.request.path_parameters"] ||= {} end - - private + def filter_parameters + # TODO: Remove dependency on controller + if controller = @env['action_controller.instance'] + controller.send(:filter_parameters, params) + else + params + end + end + + def filter_env + if controller = @env['action_controller.instance'] + @env.map do |key, value| + if (key =~ /RAW_POST_DATA/i) + '[FILTERED]' + else + controller.send(:filter_parameters, {key => value}).values[0] + end + end + else + env + end + end + + private # Convert nested Hashs to HashWithIndifferentAccess def normalize_parameters(value) case value -- cgit v1.2.3 From 93956a18e45b6bc2127da6b71dfab53516da4593 Mon Sep 17 00:00:00 2001 From: Joshua Peek Date: Wed, 20 Jan 2010 10:07:23 -0600 Subject: Only send filtered_env for notifications --- .../lib/action_dispatch/middleware/notifications.rb | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/actionpack/lib/action_dispatch/middleware/notifications.rb b/actionpack/lib/action_dispatch/middleware/notifications.rb index c3776d53a8..ce3732b740 100644 --- a/actionpack/lib/action_dispatch/middleware/notifications.rb +++ b/actionpack/lib/action_dispatch/middleware/notifications.rb @@ -9,7 +9,9 @@ module ActionDispatch end def call(env) - payload = retrieve_payload_from_env(env) + request = Request.new(env) + payload = retrieve_payload_from_env(request.filter_env) + ActiveSupport::Notifications.instrument("action_dispatch.before_dispatch", payload) ActiveSupport::Notifications.instrument!("action_dispatch.after_dispatch", payload) do @@ -21,11 +23,10 @@ module ActionDispatch raise exception end - protected - - # Remove any rack related constants from the env, like rack.input. - def retrieve_payload_from_env(env) - Hash[:env => env.except(*env.keys.select { |k| k.to_s.index("rack.") == 0 })] - end + protected + # Remove any rack related constants from the env, like rack.input. + def retrieve_payload_from_env(env) + Hash[:env => env.except(*env.keys.select { |k| k.to_s.index("rack.") == 0 })] + end end -end \ No newline at end of file +end -- 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 +----------------------------- activerecord/lib/active_record/relation.rb | 64 +++++++++++++++++++++++++++ 2 files changed, 65 insertions(+), 70 deletions(-) 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. diff --git a/activerecord/lib/active_record/relation.rb b/activerecord/lib/active_record/relation.rb index a7750f60b4..0e91959db5 100644 --- a/activerecord/lib/active_record/relation.rb +++ b/activerecord/lib/active_record/relation.rb @@ -84,6 +84,70 @@ module ActiveRecord 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 = {}) + if conditions || options.present? + where(conditions).apply_finder_options(options.slice(:limit, :order)).update_all(updates) + else + # Apply limit and order only if they're both present + if @limit_value.present? == @order_values.present? + arel.update(@klass.send(:sanitize_sql_for_assignment, updates)) + else + except(:limit, :order).update_all(updates) + end + 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 + # 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 -- cgit v1.2.3 From 459e9b29d4b9922d5ce3f87dd62fd43e752ac3da Mon Sep 17 00:00:00 2001 From: Pratik Naik Date: Wed, 20 Jan 2010 22:20:33 +0530 Subject: Use @limit_value and @offset_value instead of calling arel --- activerecord/lib/active_record/relation.rb | 2 +- activerecord/lib/active_record/relation/finder_methods.rb | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/activerecord/lib/active_record/relation.rb b/activerecord/lib/active_record/relation.rb index 0e91959db5..c9fff15199 100644 --- a/activerecord/lib/active_record/relation.rb +++ b/activerecord/lib/active_record/relation.rb @@ -80,7 +80,7 @@ module ActiveRecord if block_given? to_a.many? { |*block_args| yield(*block_args) } else - arel.send(:taken).present? ? to_a.many? : size > 1 + @limit_value.present? ? to_a.many? : size > 1 end end diff --git a/activerecord/lib/active_record/relation/finder_methods.rb b/activerecord/lib/active_record/relation/finder_methods.rb index 2e451e380b..d6d3d66642 100644 --- a/activerecord/lib/active_record/relation/finder_methods.rb +++ b/activerecord/lib/active_record/relation/finder_methods.rb @@ -272,15 +272,15 @@ module ActiveRecord result = where(primary_key.in(ids)).all expected_size = - if arel.taken && ids.size > arel.taken - arel.taken + if @limit_value && ids.size > @limit_value + @limit_value else ids.size end # 11 ids with limit 3, offset 9 should give 2 results. - if arel.skipped && (ids.size - arel.skipped < expected_size) - expected_size = ids.size - arel.skipped + if @offset_value && (ids.size - @offset_value < expected_size) + expected_size = ids.size - @offset_value end if result.size == expected_size -- cgit v1.2.3 From c8cba7db76d7128dfd8fd03de0e085c81bbed92a Mon Sep 17 00:00:00 2001 From: Sam Ruby Date: Wed, 20 Jan 2010 10:56:06 -0600 Subject: Add AD::Route#to_s Signed-off-by: Joshua Peek --- actionpack/lib/action_dispatch/routing/route.rb | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/actionpack/lib/action_dispatch/routing/route.rb b/actionpack/lib/action_dispatch/routing/route.rb index f1431e7a37..e6e44d3546 100644 --- a/actionpack/lib/action_dispatch/routing/route.rb +++ b/actionpack/lib/action_dispatch/routing/route.rb @@ -44,6 +44,12 @@ module ActionDispatch def to_a [@app, @conditions, @defaults, @name] end + + def to_s + @to_s ||= begin + "%-6s %-40s %s" % [(verb || :any).to_s.upcase, path, requirements.inspect] + end + end end end end -- cgit v1.2.3 From 8bdcb6f072d503686dc56162c107d72762a67f7d Mon Sep 17 00:00:00 2001 From: Pratik Naik Date: Thu, 21 Jan 2010 00:25:18 +0530 Subject: Always use table.* in the finder query unless specified --- activerecord/lib/active_record/relation/query_methods.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/activerecord/lib/active_record/relation/query_methods.rb b/activerecord/lib/active_record/relation/query_methods.rb index bad6fd716b..0cfe629c07 100644 --- a/activerecord/lib/active_record/relation/query_methods.rb +++ b/activerecord/lib/active_record/relation/query_methods.rb @@ -145,7 +145,7 @@ module ActiveRecord @implicit_readonly = false arel = arel.project(s) if s.present? end - elsif joins.present? + else arel = arel.project(@klass.quoted_table_name + '.*') end -- cgit v1.2.3 From 24cc9e5b4f9b729f02d2e0b56265032d08933a41 Mon Sep 17 00:00:00 2001 From: Pratik Naik Date: Thu, 21 Jan 2010 00:34:36 +0530 Subject: Relation#spawn is basically clone + reset --- activerecord/lib/active_record/relation/spawn_methods.rb | 14 ++------------ 1 file changed, 2 insertions(+), 12 deletions(-) diff --git a/activerecord/lib/active_record/relation/spawn_methods.rb b/activerecord/lib/active_record/relation/spawn_methods.rb index 1577a9b116..cccf413e67 100644 --- a/activerecord/lib/active_record/relation/spawn_methods.rb +++ b/activerecord/lib/active_record/relation/spawn_methods.rb @@ -1,17 +1,7 @@ module ActiveRecord module SpawnMethods - def spawn(arel_table = self.table) - relation = self.class.new(@klass, arel_table) - - (Relation::ASSOCIATION_METHODS + Relation::MULTI_VALUE_METHODS).each do |query_method| - relation.send(:"#{query_method}_values=", send(:"#{query_method}_values")) - end - - Relation::SINGLE_VALUE_METHODS.each do |query_method| - relation.send(:"#{query_method}_value=", send(:"#{query_method}_value")) - end - - relation + def spawn + clone.reset end def merge(r) -- 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(-) 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 fa9f000246c2f6010f18bf40237d105b782873e2 Mon Sep 17 00:00:00 2001 From: Pratik Naik Date: Thu, 21 Jan 2010 01:36:56 +0530 Subject: Use quoted_table_name with arel.from() if no from values explicitly supplied. Arel seems to be spending a lot of time figuring out the FROM value otherwise. --- activerecord/lib/active_record/relation/query_methods.rb | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/activerecord/lib/active_record/relation/query_methods.rb b/activerecord/lib/active_record/relation/query_methods.rb index 0cfe629c07..d0689cd93e 100644 --- a/activerecord/lib/active_record/relation/query_methods.rb +++ b/activerecord/lib/active_record/relation/query_methods.rb @@ -140,16 +140,18 @@ module ActiveRecord selects = @select_values.uniq + quoted_table_name = @klass.quoted_table_name + if selects.present? selects.each do |s| @implicit_readonly = false arel = arel.project(s) if s.present? end else - arel = arel.project(@klass.quoted_table_name + '.*') + arel = arel.project(quoted_table_name + '.*') end - arel = arel.from(@from_value) if @from_value.present? + arel = @from_value.present? ? arel.from(@from_value) : arel.from(quoted_table_name) case @lock_value when TrueClass -- cgit v1.2.3