From 108db00aa90fe266564483ab301cf0669cae600f Mon Sep 17 00:00:00 2001 From: Pratik Naik Date: Thu, 31 Jul 2008 15:56:46 +0100 Subject: Raise UnknownAttributeError when unknown attributes are supplied via mass assignment --- activerecord/lib/active_record/base.rb | 10 +++++++++- activerecord/test/cases/base_test.rb | 8 ++++++++ 2 files changed, 17 insertions(+), 1 deletion(-) (limited to 'activerecord') diff --git a/activerecord/lib/active_record/base.rb b/activerecord/lib/active_record/base.rb index 9cb64223e2..29c2995334 100755 --- a/activerecord/lib/active_record/base.rb +++ b/activerecord/lib/active_record/base.rb @@ -122,6 +122,10 @@ module ActiveRecord #:nodoc: class MissingAttributeError < NoMethodError end + # Raised when unknown attributes are supplied via mass assignment. + class UnknownAttributeError < NoMethodError + end + # Raised when an error occurred while doing a mass assignment to an attribute through the # attributes= method. The exception has an +attribute+ property that is the name of the # offending attribute. @@ -2400,7 +2404,11 @@ module ActiveRecord #:nodoc: attributes = remove_attributes_protected_from_mass_assignment(attributes) if guard_protected_attributes attributes.each do |k, v| - k.include?("(") ? multi_parameter_attributes << [ k, v ] : send(k + "=", v) + if k.include?("(") + multi_parameter_attributes << [ k, v ] + else + respond_to?(:"#{k}=") ? send(:"#{k}=", v) : raise(UnknownAttributeError, "unknown attribute: #{k}") + end end assign_multiparameter_attributes(multi_parameter_attributes) diff --git a/activerecord/test/cases/base_test.rb b/activerecord/test/cases/base_test.rb index 9e4f268db7..e6d1b5ddfd 100755 --- a/activerecord/test/cases/base_test.rb +++ b/activerecord/test/cases/base_test.rb @@ -904,6 +904,14 @@ class BasicsTest < ActiveRecord::TestCase assert_nil keyboard.id end + def test_mass_assigning_invalid_attribute + firm = Firm.new + + assert_raises(ActiveRecord::UnknownAttributeError) do + firm.attributes = { "id" => 5, "type" => "Client", "i_dont_even_exist" => 20 } + end + end + def test_mass_assignment_protection_on_defaults firm = Firm.new firm.attributes = { "id" => 5, "type" => "Client" } -- cgit v1.2.3 From fb5cc19707582fa61ca3e426697cc2b00e9e5ffa Mon Sep 17 00:00:00 2001 From: miloops Date: Thu, 31 Jul 2008 10:57:50 -0300 Subject: Fix HasManyThroughAssociationsTest tests. [#733 state:resolved] Signed-off-by: Pratik Naik --- .../cases/associations/has_many_through_associations_test.rb | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) (limited to 'activerecord') diff --git a/activerecord/test/cases/associations/has_many_through_associations_test.rb b/activerecord/test/cases/associations/has_many_through_associations_test.rb index be5170f830..d51a3c7e1c 100644 --- a/activerecord/test/cases/associations/has_many_through_associations_test.rb +++ b/activerecord/test/cases/associations/has_many_through_associations_test.rb @@ -2,15 +2,18 @@ require "cases/helper" require 'models/post' require 'models/person' require 'models/reader' +require 'models/comment' class HasManyThroughAssociationsTest < ActiveRecord::TestCase - fixtures :posts, :readers, :people + fixtures :posts, :readers, :people, :comments def test_associate_existing assert_queries(2) { posts(:thinking);people(:david) } - + + posts(:thinking).people + assert_queries(1) do - posts(:thinking).people << people(:david) + posts(:thinking).people << people(:david) end assert_queries(1) do -- cgit v1.2.3 From 896a3b9ab8dc02639ffa0b1dbf85011e1f3eda9b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tarmo=20T=C3=A4nav?= Date: Thu, 31 Jul 2008 19:52:35 +0300 Subject: Fixed test_joins_with_namespaced_model_should_use_correct_type for postgresql Signed-off-by: Michael Koziarski --- activerecord/test/cases/associations/has_many_associations_test.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'activerecord') diff --git a/activerecord/test/cases/associations/has_many_associations_test.rb b/activerecord/test/cases/associations/has_many_associations_test.rb index f8b8b1f96d..47e4b3527d 100644 --- a/activerecord/test/cases/associations/has_many_associations_test.rb +++ b/activerecord/test/cases/associations/has_many_associations_test.rb @@ -1007,7 +1007,7 @@ class HasManyAssociationsTest < ActiveRecord::TestCase firm.clients.create({ :name => 'Some Client' }) stats = Namespaced::Firm.find(firm.id, { - :select => "#{Namespaced::Firm.table_name}.*, COUNT(#{Namespaced::Client.table_name}.id) AS num_clients", + :select => "#{Namespaced::Firm.table_name}.id, COUNT(#{Namespaced::Client.table_name}.id) AS num_clients", :joins => :clients, :group => "#{Namespaced::Firm.table_name}.id" }) -- cgit v1.2.3 From 68b207b087588fc9a2cc8edb842408e3be5ba9ef Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tarmo=20T=C3=A4nav?= Date: Thu, 31 Jul 2008 19:26:18 +0300 Subject: Cast value to string in validates_uniqueness_of if the column is of text type This fixes an error for postgresql where "text_column = 100" fails in version 8.3 Signed-off-by: Michael Koziarski --- activerecord/lib/active_record/validations.rb | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) (limited to 'activerecord') diff --git a/activerecord/lib/active_record/validations.rb b/activerecord/lib/active_record/validations.rb index b957ee3b9e..52f674847e 100755 --- a/activerecord/lib/active_record/validations.rb +++ b/activerecord/lib/active_record/validations.rb @@ -625,7 +625,13 @@ module ActiveRecord # class (which has a database table to query from). finder_class = class_hierarchy.detect { |klass| !klass.abstract_class? } - if value.nil? || (configuration[:case_sensitive] || !finder_class.columns_hash[attr_name.to_s].text?) + is_text_column = finder_class.columns_hash[attr_name.to_s].text? + + if !value.nil? && is_text_column + value = value.to_s + end + + if value.nil? || (configuration[:case_sensitive] || !is_text_column) condition_sql = "#{record.class.quoted_table_name}.#{attr_name} #{attribute_condition(value)}" condition_params = [value] else -- cgit v1.2.3 From cb68b21a52a12b0773f0b4dac1c9c673c93ba355 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tarmo=20T=C3=A4nav?= Date: Thu, 31 Jul 2008 21:51:50 +0300 Subject: Fixed negative default integer parsing for Postgresql 8.3.3 Signed-off-by: Michael Koziarski --- .../lib/active_record/connection_adapters/postgresql_adapter.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'activerecord') diff --git a/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb b/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb index 6a20f41a4b..856435517a 100644 --- a/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb +++ b/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb @@ -182,8 +182,8 @@ module ActiveRecord def self.extract_value_from_default(default) case default # Numeric types - when /\A-?\d+(\.\d*)?\z/ - default + when /\A\(?(-?\d+(\.\d*)?\)?)\z/ + $1 # Character types when /\A'(.*)'::(?:character varying|bpchar|text)\z/m $1 -- cgit v1.2.3 From f7eaab96d332528253d14581f747dd4b1b378a06 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tarmo=20T=C3=A4nav?= Date: Thu, 31 Jul 2008 22:18:14 +0300 Subject: validates_uniqueness_of uses database case sensitivity support instead of using ruby Signed-off-by: Michael Koziarski --- .../abstract/database_statements.rb | 4 +++ .../connection_adapters/mysql_adapter.rb | 4 +++ activerecord/lib/active_record/validations.rb | 42 ++++++++-------------- 3 files changed, 23 insertions(+), 27 deletions(-) (limited to 'activerecord') diff --git a/activerecord/lib/active_record/connection_adapters/abstract/database_statements.rb b/activerecord/lib/active_record/connection_adapters/abstract/database_statements.rb index 5358491cde..aaf9e2e73f 100644 --- a/activerecord/lib/active_record/connection_adapters/abstract/database_statements.rb +++ b/activerecord/lib/active_record/connection_adapters/abstract/database_statements.rb @@ -149,6 +149,10 @@ module ActiveRecord "INSERT INTO #{quote_table_name(table_name)} VALUES(DEFAULT)" end + def case_sensitive_equality_operator + "=" + end + protected # Returns an array of record hashes with the column names as keys and # column values as values. diff --git a/activerecord/lib/active_record/connection_adapters/mysql_adapter.rb b/activerecord/lib/active_record/connection_adapters/mysql_adapter.rb index 35b9ed4746..204ebaa2e2 100755 --- a/activerecord/lib/active_record/connection_adapters/mysql_adapter.rb +++ b/activerecord/lib/active_record/connection_adapters/mysql_adapter.rb @@ -511,6 +511,10 @@ module ActiveRecord keys.length == 1 ? [keys.first, nil] : nil end + def case_sensitive_equality_operator + "= BINARY" + end + private def connect @connection.reconnect = true if @connection.respond_to?(:reconnect=) diff --git a/activerecord/lib/active_record/validations.rb b/activerecord/lib/active_record/validations.rb index 52f674847e..e7a9676394 100755 --- a/activerecord/lib/active_record/validations.rb +++ b/activerecord/lib/active_record/validations.rb @@ -627,17 +627,23 @@ module ActiveRecord is_text_column = finder_class.columns_hash[attr_name.to_s].text? - if !value.nil? && is_text_column - value = value.to_s + if value.nil? + comparison_operator = "IS ?" + else + comparison_operator = "#{connection.case_sensitive_equality_operator} ?" + + if is_text_column + value = value.to_s + end end + sql_attribute = "#{record.class.quoted_table_name}.#{connection.quote_column_name(attr_name)}" + if value.nil? || (configuration[:case_sensitive] || !is_text_column) - condition_sql = "#{record.class.quoted_table_name}.#{attr_name} #{attribute_condition(value)}" + condition_sql = "#{sql_attribute} #{comparison_operator}" condition_params = [value] else - # sqlite has case sensitive SELECT query, while MySQL/Postgresql don't. - # Hence, this is needed only for sqlite. - condition_sql = "LOWER(#{record.class.quoted_table_name}.#{attr_name}) #{attribute_condition(value)}" + condition_sql = "LOWER(#{sql_attribute}) #{comparison_operator}" condition_params = [value.downcase] end @@ -654,28 +660,10 @@ module ActiveRecord condition_params << record.send(:id) end - results = finder_class.with_exclusive_scope do - connection.select_all( - construct_finder_sql( - :select => "#{connection.quote_column_name(attr_name)}", - :from => "#{finder_class.quoted_table_name}", - :conditions => [condition_sql, *condition_params] - ) - ) - end - - unless results.length.zero? - found = true - - # As MySQL/Postgres don't have case sensitive SELECT queries, we try to find duplicate - # column in ruby when case sensitive option - if configuration[:case_sensitive] && finder_class.columns_hash[attr_name.to_s].text? - found = results.any? { |a| a[attr_name.to_s] == value.to_s } - end - - if found + finder_class.with_exclusive_scope do + if finder_class.exists?([condition_sql, *condition_params]) message = record.errors.generate_message(attr_name, :taken, :default => configuration[:message]) - record.errors.add(attr_name, message) + record.errors.add(attr_name, message) end end end -- cgit v1.2.3 From 656f0e7c6c9a305abaf9f9b7fb80479b6f94efce Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tarmo=20T=C3=A4nav?= Date: Thu, 31 Jul 2008 16:36:23 -0500 Subject: Fix file permissions Signed-off-by: Joshua Peek --- activerecord/README | 0 activerecord/Rakefile | 0 activerecord/lib/active_record.rb | 0 activerecord/lib/active_record/associations.rb | 0 activerecord/lib/active_record/associations/belongs_to_association.rb | 0 .../lib/active_record/associations/belongs_to_polymorphic_association.rb | 0 activerecord/lib/active_record/associations/has_one_association.rb | 0 activerecord/lib/active_record/base.rb | 0 activerecord/lib/active_record/callbacks.rb | 0 activerecord/lib/active_record/connection_adapters/abstract_adapter.rb | 0 activerecord/lib/active_record/connection_adapters/mysql_adapter.rb | 0 activerecord/lib/active_record/fixtures.rb | 0 activerecord/lib/active_record/validations.rb | 0 activerecord/test/cases/associations/belongs_to_associations_test.rb | 0 activerecord/test/cases/associations/has_one_associations_test.rb | 0 activerecord/test/cases/associations_test.rb | 0 activerecord/test/cases/attribute_methods_test.rb | 0 activerecord/test/cases/base_test.rb | 0 activerecord/test/cases/deprecated_finder_test.rb | 0 activerecord/test/cases/fixtures_test.rb | 0 activerecord/test/cases/inheritance_test.rb | 0 activerecord/test/cases/lifecycle_test.rb | 0 activerecord/test/cases/readonly_test.rb | 0 activerecord/test/cases/unconnected_test.rb | 0 activerecord/test/cases/validations_test.rb | 0 activerecord/test/models/company.rb | 0 activerecord/test/models/reply.rb | 0 activerecord/test/models/topic.rb | 0 28 files changed, 0 insertions(+), 0 deletions(-) mode change 100755 => 100644 activerecord/README mode change 100755 => 100644 activerecord/Rakefile mode change 100755 => 100644 activerecord/lib/active_record.rb mode change 100755 => 100644 activerecord/lib/active_record/associations.rb mode change 100755 => 100644 activerecord/lib/active_record/associations/belongs_to_association.rb mode change 100755 => 100644 activerecord/lib/active_record/associations/belongs_to_polymorphic_association.rb mode change 100755 => 100644 activerecord/lib/active_record/associations/has_one_association.rb mode change 100755 => 100644 activerecord/lib/active_record/base.rb mode change 100755 => 100644 activerecord/lib/active_record/callbacks.rb mode change 100755 => 100644 activerecord/lib/active_record/connection_adapters/abstract_adapter.rb mode change 100755 => 100644 activerecord/lib/active_record/connection_adapters/mysql_adapter.rb mode change 100755 => 100644 activerecord/lib/active_record/fixtures.rb mode change 100755 => 100644 activerecord/lib/active_record/validations.rb mode change 100755 => 100644 activerecord/test/cases/associations/belongs_to_associations_test.rb mode change 100755 => 100644 activerecord/test/cases/associations/has_one_associations_test.rb mode change 100755 => 100644 activerecord/test/cases/associations_test.rb mode change 100755 => 100644 activerecord/test/cases/attribute_methods_test.rb mode change 100755 => 100644 activerecord/test/cases/base_test.rb mode change 100755 => 100644 activerecord/test/cases/deprecated_finder_test.rb mode change 100755 => 100644 activerecord/test/cases/fixtures_test.rb mode change 100755 => 100644 activerecord/test/cases/inheritance_test.rb mode change 100755 => 100644 activerecord/test/cases/lifecycle_test.rb mode change 100755 => 100644 activerecord/test/cases/readonly_test.rb mode change 100755 => 100644 activerecord/test/cases/unconnected_test.rb mode change 100755 => 100644 activerecord/test/cases/validations_test.rb mode change 100755 => 100644 activerecord/test/models/company.rb mode change 100755 => 100644 activerecord/test/models/reply.rb mode change 100755 => 100644 activerecord/test/models/topic.rb (limited to 'activerecord') diff --git a/activerecord/README b/activerecord/README old mode 100755 new mode 100644 diff --git a/activerecord/Rakefile b/activerecord/Rakefile old mode 100755 new mode 100644 diff --git a/activerecord/lib/active_record.rb b/activerecord/lib/active_record.rb old mode 100755 new mode 100644 diff --git a/activerecord/lib/active_record/associations.rb b/activerecord/lib/active_record/associations.rb old mode 100755 new mode 100644 diff --git a/activerecord/lib/active_record/associations/belongs_to_association.rb b/activerecord/lib/active_record/associations/belongs_to_association.rb old mode 100755 new mode 100644 diff --git a/activerecord/lib/active_record/associations/belongs_to_polymorphic_association.rb b/activerecord/lib/active_record/associations/belongs_to_polymorphic_association.rb old mode 100755 new mode 100644 diff --git a/activerecord/lib/active_record/associations/has_one_association.rb b/activerecord/lib/active_record/associations/has_one_association.rb old mode 100755 new mode 100644 diff --git a/activerecord/lib/active_record/base.rb b/activerecord/lib/active_record/base.rb old mode 100755 new mode 100644 diff --git a/activerecord/lib/active_record/callbacks.rb b/activerecord/lib/active_record/callbacks.rb old mode 100755 new mode 100644 diff --git a/activerecord/lib/active_record/connection_adapters/abstract_adapter.rb b/activerecord/lib/active_record/connection_adapters/abstract_adapter.rb old mode 100755 new mode 100644 diff --git a/activerecord/lib/active_record/connection_adapters/mysql_adapter.rb b/activerecord/lib/active_record/connection_adapters/mysql_adapter.rb old mode 100755 new mode 100644 diff --git a/activerecord/lib/active_record/fixtures.rb b/activerecord/lib/active_record/fixtures.rb old mode 100755 new mode 100644 diff --git a/activerecord/lib/active_record/validations.rb b/activerecord/lib/active_record/validations.rb old mode 100755 new mode 100644 diff --git a/activerecord/test/cases/associations/belongs_to_associations_test.rb b/activerecord/test/cases/associations/belongs_to_associations_test.rb old mode 100755 new mode 100644 diff --git a/activerecord/test/cases/associations/has_one_associations_test.rb b/activerecord/test/cases/associations/has_one_associations_test.rb old mode 100755 new mode 100644 diff --git a/activerecord/test/cases/associations_test.rb b/activerecord/test/cases/associations_test.rb old mode 100755 new mode 100644 diff --git a/activerecord/test/cases/attribute_methods_test.rb b/activerecord/test/cases/attribute_methods_test.rb old mode 100755 new mode 100644 diff --git a/activerecord/test/cases/base_test.rb b/activerecord/test/cases/base_test.rb old mode 100755 new mode 100644 diff --git a/activerecord/test/cases/deprecated_finder_test.rb b/activerecord/test/cases/deprecated_finder_test.rb old mode 100755 new mode 100644 diff --git a/activerecord/test/cases/fixtures_test.rb b/activerecord/test/cases/fixtures_test.rb old mode 100755 new mode 100644 diff --git a/activerecord/test/cases/inheritance_test.rb b/activerecord/test/cases/inheritance_test.rb old mode 100755 new mode 100644 diff --git a/activerecord/test/cases/lifecycle_test.rb b/activerecord/test/cases/lifecycle_test.rb old mode 100755 new mode 100644 diff --git a/activerecord/test/cases/readonly_test.rb b/activerecord/test/cases/readonly_test.rb old mode 100755 new mode 100644 diff --git a/activerecord/test/cases/unconnected_test.rb b/activerecord/test/cases/unconnected_test.rb old mode 100755 new mode 100644 diff --git a/activerecord/test/cases/validations_test.rb b/activerecord/test/cases/validations_test.rb old mode 100755 new mode 100644 diff --git a/activerecord/test/models/company.rb b/activerecord/test/models/company.rb old mode 100755 new mode 100644 diff --git a/activerecord/test/models/reply.rb b/activerecord/test/models/reply.rb old mode 100755 new mode 100644 diff --git a/activerecord/test/models/topic.rb b/activerecord/test/models/topic.rb old mode 100755 new mode 100644 -- cgit v1.2.3