diff options
author | Ryuta Kamizono <kamipo@gmail.com> | 2019-03-11 01:30:40 +0900 |
---|---|---|
committer | Ryuta Kamizono <kamipo@gmail.com> | 2019-03-11 01:35:46 +0900 |
commit | 260a3c65122a726eea20828d4909e15502751c39 (patch) | |
tree | c8db53f063248e33d4377cee9e1721d8f697e0e3 | |
parent | b75d6ea5d35d61c60f2675ed956c51e71d2b07ad (diff) | |
parent | 81bc621ed01637e8305fb53c9e504b1cc46c102f (diff) | |
download | rails-260a3c65122a726eea20828d4909e15502751c39.tar.gz rails-260a3c65122a726eea20828d4909e15502751c39.tar.bz2 rails-260a3c65122a726eea20828d4909e15502751c39.zip |
Merge pull request #35320 from kamille-gz/fix_query_method_when_given_Date_data_type
Fix ActiveRecord query attribute method when given value does't respond to to_i method
-rw-r--r-- | activerecord/CHANGELOG.md | 14 | ||||
-rw-r--r-- | activerecord/lib/active_record/attribute_methods/query.rb | 3 | ||||
-rw-r--r-- | activerecord/test/cases/attribute_methods_test.rb | 63 |
3 files changed, 78 insertions, 2 deletions
diff --git a/activerecord/CHANGELOG.md b/activerecord/CHANGELOG.md index c0ef3cbe7c..2d260f2bf5 100644 --- a/activerecord/CHANGELOG.md +++ b/activerecord/CHANGELOG.md @@ -1,3 +1,17 @@ +* Fix query attribute method on user-defined attribute to be aware of typecasted value. + + For example, the following code no longer return false as casted non-empty string: + + ``` + class Post < ActiveRecord::Base + attribute :user_defined_text, :text + end + + Post.new(user_defined_text: "false").user_defined_text? # => true + ``` + + *Yuji Kamijima* + * Quote empty ranges like other empty enumerables. *Patrick Rebsch* diff --git a/activerecord/lib/active_record/attribute_methods/query.rb b/activerecord/lib/active_record/attribute_methods/query.rb index 6757e9b66a..6811f54b10 100644 --- a/activerecord/lib/active_record/attribute_methods/query.rb +++ b/activerecord/lib/active_record/attribute_methods/query.rb @@ -16,8 +16,7 @@ module ActiveRecord when true then true when false, nil then false else - column = self.class.columns_hash[attr_name] - if column.nil? + if !type_for_attribute(attr_name) { false } if Numeric === value || value !~ /[^0-9]/ !value.to_i.zero? else diff --git a/activerecord/test/cases/attribute_methods_test.rb b/activerecord/test/cases/attribute_methods_test.rb index 12ff6d4826..f51c87ef2b 100644 --- a/activerecord/test/cases/attribute_methods_test.rb +++ b/activerecord/test/cases/attribute_methods_test.rb @@ -458,6 +458,69 @@ class AttributeMethodsTest < ActiveRecord::TestCase end end + test "user-defined text attribute predicate" do + klass = Class.new(ActiveRecord::Base) do + self.table_name = Topic.table_name + + attribute :user_defined_text, :text + end + + topic = klass.new(user_defined_text: "text") + assert_predicate topic, :user_defined_text? + + ActiveModel::Type::Boolean::FALSE_VALUES.each do |value| + topic = klass.new(user_defined_text: value) + assert_predicate topic, :user_defined_text? + end + end + + test "user-defined date attribute predicate" do + klass = Class.new(ActiveRecord::Base) do + self.table_name = Topic.table_name + + attribute :user_defined_date, :date + end + + topic = klass.new(user_defined_date: Date.current) + assert_predicate topic, :user_defined_date? + end + + test "user-defined datetime attribute predicate" do + klass = Class.new(ActiveRecord::Base) do + self.table_name = Topic.table_name + + attribute :user_defined_datetime, :datetime + end + + topic = klass.new(user_defined_datetime: Time.current) + assert_predicate topic, :user_defined_datetime? + end + + test "user-defined time attribute predicate" do + klass = Class.new(ActiveRecord::Base) do + self.table_name = Topic.table_name + + attribute :user_defined_time, :time + end + + topic = klass.new(user_defined_time: Time.current) + assert_predicate topic, :user_defined_time? + end + + test "user-defined json attribute predicate" do + klass = Class.new(ActiveRecord::Base) do + self.table_name = Topic.table_name + + attribute :user_defined_json, :json + end + + topic = klass.new(user_defined_json: { key: "value" }) + assert_predicate topic, :user_defined_json? + + topic = klass.new(user_defined_json: {}) + assert_not_predicate topic, :user_defined_json? + end + test "custom field attribute predicate" do object = Company.find_by_sql(<<~SQL).first SELECT c1.*, c2.type as string_value, c2.rating as int_value |