diff options
19 files changed, 180 insertions, 55 deletions
diff --git a/actionmailer/README.rdoc b/actionmailer/README.rdoc index 67b64fe469..ceca912ada 100644 --- a/actionmailer/README.rdoc +++ b/actionmailer/README.rdoc @@ -156,7 +156,11 @@ API documentation is at * http://api.rubyonrails.org -Bug reports and feature requests can be filed with the rest for the Ruby on Rails project here: +Bug reports can be filed for the Ruby on Rails project here: * https://github.com/rails/rails/issues +Feature requests should be discussed on the rails-core mailing list here: + +* https://groups.google.com/forum/?fromgroups#!forum/rubyonrails-core + diff --git a/actionpack/README.rdoc b/actionpack/README.rdoc index 2f6575c3b5..02a24a7412 100644 --- a/actionpack/README.rdoc +++ b/actionpack/README.rdoc @@ -48,6 +48,11 @@ API documentation is at * http://api.rubyonrails.org -Bug reports and feature requests can be filed with the rest for the Ruby on Rails project here: +Bug reports can be filed for the Ruby on Rails project here: * https://github.com/rails/rails/issues + +Feature requests should be discussed on the rails-core mailing list here: + +* https://groups.google.com/forum/?fromgroups#!forum/rubyonrails-core + diff --git a/actionview/README.rdoc b/actionview/README.rdoc index 35f805346c..5bb62c7562 100644 --- a/actionview/README.rdoc +++ b/actionview/README.rdoc @@ -29,6 +29,11 @@ API documentation is at * http://api.rubyonrails.org -Bug reports and feature requests can be filed with the rest for the Ruby on Rails project here: +Bug reports can be filed for the Ruby on Rails project here: * https://github.com/rails/rails/issues + +Feature requests should be discussed on the rails-core mailing list here: + +* https://groups.google.com/forum/?fromgroups#!forum/rubyonrails-core + diff --git a/activemodel/README.rdoc b/activemodel/README.rdoc index c6500f47e2..f6beff14e1 100644 --- a/activemodel/README.rdoc +++ b/activemodel/README.rdoc @@ -262,6 +262,11 @@ API documentation is at * http://api.rubyonrails.org -Bug reports and feature requests can be filed with the rest for the Ruby on Rails project here: +Bug reports can be filed for the Ruby on Rails project here: * https://github.com/rails/rails/issues + +Feature requests should be discussed on the rails-core mailing list here: + +* https://groups.google.com/forum/?fromgroups#!forum/rubyonrails-core + diff --git a/activerecord/CHANGELOG.md b/activerecord/CHANGELOG.md index 078d63f8f2..9da1304953 100644 --- a/activerecord/CHANGELOG.md +++ b/activerecord/CHANGELOG.md @@ -1,3 +1,7 @@ +* New records remain new after YAML serialization. + + *Sean Griffin* + * PostgreSQL support default values for enum types. Fixes #7814. *Yves Senn* diff --git a/activerecord/README.rdoc b/activerecord/README.rdoc index 969e97913d..f4777919d3 100644 --- a/activerecord/README.rdoc +++ b/activerecord/README.rdoc @@ -208,6 +208,11 @@ API documentation is at: * http://api.rubyonrails.org -Bug reports and feature requests can be filed with the rest for the Ruby on Rails project here: +Bug reports can be filed for the Ruby on Rails project here: * https://github.com/rails/rails/issues + +Feature requests should be discussed on the rails-core mailing list here: + +* https://groups.google.com/forum/?fromgroups#!forum/rubyonrails-core + diff --git a/activerecord/lib/active_record/connection_adapters/postgresql/cast.rb b/activerecord/lib/active_record/connection_adapters/postgresql/cast.rb index f7bad20f00..971f5eed7e 100644 --- a/activerecord/lib/active_record/connection_adapters/postgresql/cast.rb +++ b/activerecord/lib/active_record/connection_adapters/postgresql/cast.rb @@ -6,15 +6,6 @@ module ActiveRecord "(#{point[0]},#{point[1]})" end - def string_to_bit(value) # :nodoc: - case value - when /^0x/i - value[2..-1].hex.to_s(2) # Hexadecimal notation - else - value # Bit-string notation - end - end - def hstore_to_string(object, array_member = false) # :nodoc: if Hash === object string = object.map { |k, v| "#{escape_hstore(k)}=>#{escape_hstore(v)}" }.join(',') @@ -76,28 +67,6 @@ module ActiveRecord end end - def string_to_cidr(string) # :nodoc: - if string.nil? - nil - elsif String === string - begin - IPAddr.new(string) - rescue ArgumentError - nil - end - else - string - end - end - - def cidr_to_string(object) # :nodoc: - if IPAddr === object - "#{object.to_s}/#{object.instance_variable_get(:@mask_addr).to_s(2).count('1')}" - else - object - end - end - def string_to_array(string, oid) # :nodoc: parse_pg_array(string).map {|val| type_cast_array(oid, val)} end diff --git a/activerecord/lib/active_record/connection_adapters/postgresql/oid/bit.rb b/activerecord/lib/active_record/connection_adapters/postgresql/oid/bit.rb index 9b2d887d07..dc077993c5 100644 --- a/activerecord/lib/active_record/connection_adapters/postgresql/oid/bit.rb +++ b/activerecord/lib/active_record/connection_adapters/postgresql/oid/bit.rb @@ -5,7 +5,12 @@ module ActiveRecord class Bit < Type::String def type_cast(value) if ::String === value - ConnectionAdapters::PostgreSQLColumn.string_to_bit value + case value + when /^0x/i + value[2..-1].hex.to_s(2) # Hexadecimal notation + else + value # Bit-string notation + end else value end diff --git a/activerecord/lib/active_record/connection_adapters/postgresql/oid/cidr.rb b/activerecord/lib/active_record/connection_adapters/postgresql/oid/cidr.rb index 158468fe5b..534961a414 100644 --- a/activerecord/lib/active_record/connection_adapters/postgresql/oid/cidr.rb +++ b/activerecord/lib/active_record/connection_adapters/postgresql/oid/cidr.rb @@ -18,8 +18,26 @@ module ActiveRecord end end + def type_cast_for_database(value) + if IPAddr === value + "#{value.to_s}/#{value.instance_variable_get(:@mask_addr).to_s(2).count('1')}" + else + value + end + end + def cast_value(value) - ConnectionAdapters::PostgreSQLColumn.string_to_cidr value + if value.nil? + nil + elsif String === value + begin + IPAddr.new(value) + rescue ArgumentError + nil + end + else + value + end end end end diff --git a/activerecord/lib/active_record/connection_adapters/postgresql/quoting.rb b/activerecord/lib/active_record/connection_adapters/postgresql/quoting.rb index 7b7144a3a8..c875bc5162 100644 --- a/activerecord/lib/active_record/connection_adapters/postgresql/quoting.rb +++ b/activerecord/lib/active_record/connection_adapters/postgresql/quoting.rb @@ -44,11 +44,6 @@ module ActiveRecord when 'json' then super(PostgreSQLColumn.json_to_string(value), column) else super end - when IPAddr - case sql_type - when 'inet', 'cidr' then super(PostgreSQLColumn.cidr_to_string(value), column) - else super - end when Float if value.infinite? && column.type == :datetime "'#{value.to_s.downcase}'" @@ -125,12 +120,6 @@ module ActiveRecord when 'json' then PostgreSQLColumn.json_to_string(value) else super(value, column) end - when IPAddr - if %w(inet cidr).include? column.sql_type - PostgreSQLColumn.cidr_to_string(value) - else - super(value, column) - end else super(value, column) end diff --git a/activerecord/lib/active_record/core.rb b/activerecord/lib/active_record/core.rb index 205cae9b2a..88c1fc7e4c 100644 --- a/activerecord/lib/active_record/core.rb +++ b/activerecord/lib/active_record/core.rb @@ -284,7 +284,7 @@ module ActiveRecord init_internals - @new_record = false + @new_record = coder['new_record'] self.class.define_attribute_methods @@ -354,6 +354,7 @@ module ActiveRecord # coder # => {"attributes" => {"id" => nil, ... }} def encode_with(coder) coder['attributes'] = @raw_attributes + coder['new_record'] = new_record? end # Returns true if +comparison_object+ is the same exact object, or +comparison_object+ diff --git a/activerecord/lib/active_record/persistence.rb b/activerecord/lib/active_record/persistence.rb index 78ae05073a..2e3bcc0956 100644 --- a/activerecord/lib/active_record/persistence.rb +++ b/activerecord/lib/active_record/persistence.rb @@ -49,7 +49,11 @@ module ActiveRecord def instantiate(attributes, column_types = {}) klass = discriminate_class_for_record(attributes) column_types = klass.decorate_columns(column_types.dup) - klass.allocate.init_with('attributes' => attributes, 'column_types' => column_types) + klass.allocate.init_with( + 'attributes' => attributes, + 'column_types' => column_types, + 'new_record' => false, + ) end private diff --git a/activerecord/lib/active_record/type/value.rb b/activerecord/lib/active_record/type/value.rb index 8cd99df2b4..1f7d4e20b2 100644 --- a/activerecord/lib/active_record/type/value.rb +++ b/activerecord/lib/active_record/type/value.rb @@ -12,8 +12,8 @@ module ActiveRecord @limit = options[:limit] end - # The simplified that this object represents. Subclasses - # should override this method. + # The simplified type that this object represents. Subclasses + # must override this method. def type; end # Takes an input from the database, or from attribute setters, diff --git a/activerecord/test/cases/adapters/postgresql/geometric_test.rb b/activerecord/test/cases/adapters/postgresql/geometric_test.rb new file mode 100644 index 0000000000..775b1d2d69 --- /dev/null +++ b/activerecord/test/cases/adapters/postgresql/geometric_test.rb @@ -0,0 +1,45 @@ +# -*- coding: utf-8 -*- +require "cases/helper" +require 'support/connection_helper' +require 'active_record/base' +require 'active_record/connection_adapters/postgresql_adapter' + +class PostgresqlPointTest < ActiveRecord::TestCase + include ConnectionHelper + + class PostgresqlPoint < ActiveRecord::Base; end + + def setup + @connection = ActiveRecord::Base.connection + @connection.transaction do + @connection.create_table('postgresql_points') do |t| + t.column :x, :point + end + end + end + + teardown do + @connection.execute 'DROP TABLE IF EXISTS postgresql_points' + end + + def test_column + column = PostgresqlPoint.columns_hash["x"] + assert_equal :string, column.type + assert_equal "point", column.sql_type + assert column.text? + assert_not column.number? + assert_not column.binary? + assert_not column.array + end + + def test_roundtrip + PostgresqlPoint.create! x: [10, 25.2] + record = PostgresqlPoint.first + assert_equal [10, 25.2], record.x + + record.x = [1.1, 2.2] + record.save! + assert record.reload + assert_equal [1.1, 2.2], record.x + end +end diff --git a/activerecord/test/cases/yaml_serialization_test.rb b/activerecord/test/cases/yaml_serialization_test.rb index f7af9a35cd..d4f8ef5b4d 100644 --- a/activerecord/test/cases/yaml_serialization_test.rb +++ b/activerecord/test/cases/yaml_serialization_test.rb @@ -52,4 +52,21 @@ class YamlSerializationTest < ActiveRecord::TestCase assert_equal 123, topic.parent_id assert_equal 123, YAML.load(YAML.dump(topic)).parent_id end + + def test_new_records_remain_new_after_round_trip + topic = Topic.new + + assert topic.new_record?, "Sanity check that new records are new" + assert YAML.load(YAML.dump(topic)).new_record?, "Record should be new after deserialization" + + topic.save! + + assert_not topic.new_record?, "Saved records are not new" + assert_not YAML.load(YAML.dump(topic)).new_record?, "Saved record should not be new after deserialization" + + topic = Topic.select('title').last + + assert_not topic.new_record?, "Loaded records without ID are not new" + assert_not YAML.load(YAML.dump(topic)).new_record?, "Record should not be new after deserialization" + end end diff --git a/activesupport/README.rdoc b/activesupport/README.rdoc index f3582767c0..a6424a353a 100644 --- a/activesupport/README.rdoc +++ b/activesupport/README.rdoc @@ -30,6 +30,11 @@ API documentation is at: * http://api.rubyonrails.org -Bug reports and feature requests can be filed with the rest for the Ruby on Rails project here: +Bug reports can be filed for the Ruby on Rails project here: * https://github.com/rails/rails/issues + +Feature requests should be discussed on the rails-core mailing list here: + +* https://groups.google.com/forum/?fromgroups#!forum/rubyonrails-core + diff --git a/guides/source/active_record_querying.md b/guides/source/active_record_querying.md index ee8cf4ade6..673dcfc1d3 100644 --- a/guides/source/active_record_querying.md +++ b/guides/source/active_record_querying.md @@ -659,6 +659,23 @@ FROM orders GROUP BY date(created_at) ``` +### Total of grouped items + +To get the total of grouped items on a single query call `count` after the `group`. + +```ruby +Order.group(:status).count +# => { 'awaiting_approval' => 7, 'paid' => 12 } +``` + +The SQL that would be executed would be something like this: + +```sql +SELECT COUNT (*) AS count_all, status AS status +FROM "orders" +GROUP BY status +``` + Having ------ diff --git a/guides/source/migrations.md b/guides/source/migrations.md index 6742c05946..31e314c69b 100644 --- a/guides/source/migrations.md +++ b/guides/source/migrations.md @@ -415,6 +415,29 @@ end removes the `description` and `name` columns, creates a `part_number` string column and adds an index on it. Finally it renames the `upccode` column. +### Changing Columns + +Like the `remove_column` and `add_column` Rails provides the `change_column` +migration method. + +```ruby +change_column :products, :part_number, :text +``` + +This changes the column `part_number` on products table to be a `:text` field. + +Besides `change_column`, the `change_column_null` and `change_column_default` +methods are used specifically to change the null and default values of a +column. + +```ruby +change_column_null :products, :name, false +change_column_default :products, :approved, false +``` + +This sets `:name` field on products to a `NOT NULL` column and the default +value of the `:approved` field to false. + ### When Helpers aren't Enough If the helpers provided by Active Record aren't enough you can use the `execute` diff --git a/railties/README.rdoc b/railties/README.rdoc index 6248b5feed..a25658668c 100644 --- a/railties/README.rdoc +++ b/railties/README.rdoc @@ -31,7 +31,11 @@ API documentation is at * http://api.rubyonrails.org -Bug reports and feature requests can be filed with the rest for the Ruby on Rails project here: +Bug reports can be filed for the Ruby on Rails project here: * https://github.com/rails/rails/issues +Feature requests should be discussed on the rails-core mailing list here: + +* https://groups.google.com/forum/?fromgroups#!forum/rubyonrails-core + |