Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- From 622d0ffcfa65a500da995e74f6765b3788cc3539 Mon Sep 17 00:00:00 2001
- From: Taryn East <git@taryneast.org>
- Date: Wed, 2 Dec 2009 21:50:55 +0000
- Subject: [PATCH] Bare essentials of the schema - an array on ARes
- So, we will be embarking on the grand adventure of schema-dom for Active
- Resource. Begun by a very simple array being stored on the Active Resource
- object.
- This is clearly not useful for anything at this stage, but sets up the
- foundatin for all the rest of the funtionality.
- From here we can 'complicate' things by making the schema migration-like and
- actually using it to do useful stuff... but for now, this is the beginning.
- ---
- activeresource/lib/active_resource/base.rb | 16 ++++
- activeresource/test/cases/base/schema_test.rb | 115 +++++++++++++++++++++++++
- 2 files changed, 131 insertions(+), 0 deletions(-)
- create mode 100644 activeresource/test/cases/base/schema_test.rb
- diff --git a/activeresource/lib/active_resource/base.rb b/activeresource/lib/active_resource/base.rb
- index 18105e8..b8aa028 100644
- --- a/activeresource/lib/active_resource/base.rb
- +++ b/activeresource/lib/active_resource/base.rb
- @@ -241,6 +241,15 @@ module ActiveResource
- cattr_accessor :logger
- class << self
- + # Schema defines the known attributes of the current model.
- + #
- + # TODO: under construction - will add more doco as I go.
- + def schema=(the_schema)
- + @schema = the_schema
- + end
- + def schema
- + @schema ||= nil
- + end
- # Gets the URI of the REST resources to map for this class. The site variable is required for
- # Active Resource's mapping to work.
- def site
- @@ -776,6 +785,13 @@ module ActiveResource
- attr_accessor :attributes #:nodoc:
- attr_accessor :prefix_options #:nodoc:
- + # If no schema has been defined for the class (see
- + # <tt>ActiveResource::schema=</tt>), the default automatic schema is
- + # generated from the current instance's attributes
- + def schema
- + self.class.schema || self.attributes.keys
- + end
- +
- # Constructor method for \new resources; the optional +attributes+ parameter takes a \hash
- # of attributes for the \new resource.
- #
- diff --git a/activeresource/test/cases/base/schema_test.rb b/activeresource/test/cases/base/schema_test.rb
- new file mode 100644
- index 0000000..2fb2707
- --- /dev/null
- +++ b/activeresource/test/cases/base/schema_test.rb
- @@ -0,0 +1,115 @@
- +require 'abstract_unit'
- +require "fixtures/person"
- +require "fixtures/street_address"
- +
- +########################################################################
- +# Testing the schema of your Active Resource models
- +########################################################################
- +class SchemaTest < ActiveModel::TestCase
- + def setup
- + @matz = { :id => 1, :name => 'Matz' }.to_xml(:root => 'person')
- + @david = { :id => 2, :name => 'David' }.to_xml(:root => 'person')
- + @greg = { :id => 3, :name => 'Greg' }.to_xml(:root => 'person')
- + @addy = { :id => 1, :street => '12345 Street', :country => 'Australia' }.to_xml(:root => 'address')
- + @default_request_headers = { 'Content-Type' => 'application/xml' }
- + @rick = { :name => "Rick", :age => 25 }.to_xml(:root => "person")
- + @people = [{ :id => 1, :name => 'Matz' }, { :id => 2, :name => 'David' }].to_xml(:root => 'people')
- + @people_david = [{ :id => 2, :name => 'David' }].to_xml(:root => 'people')
- + @addresses = [{ :id => 1, :street => '12345 Street', :country => 'Australia' }].to_xml(:root => 'addresses')
- +
- + ActiveResource::HttpMock.respond_to do |mock|
- + mock.get "/people/1.xml", {}, @matz
- + mock.get "/people/2.xml", {}, @david
- + mock.get "/people/Greg.xml", {}, @greg
- + mock.get "/people/4.xml", {'key' => 'value'}, nil, 404
- + mock.get "/people/5.xml", {}, @rick
- + mock.put "/people/1.xml", {}, nil, 204
- + mock.delete "/people/1.xml", {}, nil, 200
- + mock.delete "/people/2.xml", {}, nil, 400
- + mock.get "/people/99.xml", {}, nil, 404
- + mock.post "/people.xml", {}, @rick, 201, 'Location' => '/people/5.xml'
- + mock.get "/people.xml", {}, @people
- + mock.get "/people/1/addresses.xml", {}, @addresses
- + mock.get "/people/1/addresses/1.xml", {}, @addy
- + mock.get "/people/1/addresses/2.xml", {}, nil, 404
- + mock.get "/people/2/addresses/1.xml", {}, nil, 404
- + mock.get "/people/Greg/addresses/1.xml", {}, @addy
- + mock.put "/people/1/addresses/1.xml", {}, nil, 204
- + mock.delete "/people/1/addresses/1.xml", {}, nil, 200
- + mock.post "/people/1/addresses.xml", {}, nil, 201, 'Location' => '/people/1/addresses/5'
- + mock.get "/people//addresses.xml", {}, nil, 404
- + mock.get "/people//addresses/1.xml", {}, nil, 404
- + mock.put "/people//addressaddresseses/1.xml", {}, nil, 404
- + mock.delete "/people//addresses/1.xml", {}, nil, 404
- + mock.post "/people//addresses.xml", {}, nil, 404
- + mock.head "/people/1.xml", {}, nil, 200
- + mock.head "/people/Greg.xml", {}, nil, 200
- + mock.head "/people/99.xml", {}, nil, 404
- + mock.head "/people/1/addresses/1.xml", {}, nil, 200
- + mock.head "/people/1/addresses/2.xml", {}, nil, 404
- + mock.head "/people/2/addresses/1.xml", {}, nil, 404
- + mock.head "/people/Greg/addresses/1.xml", {}, nil, 200
- + end
- +
- + Person.user = nil
- + Person.password = nil
- + end
- +
- + test "schema on a new model should be empty" do
- + assert Person.schema.blank?, "should have a blank class schema"
- + assert Person.new.schema.blank?, "should have a blank instance schema"
- + end
- +
- + test "schema on a found model should return all the attributes of that model instance" do
- + p = Person.find(1)
- + s = p.schema
- +
- + assert s.present?, "should have found a non-empty schema!"
- +
- + p.attributes.each do |the_attr, val|
- + assert s.include?(the_attr), "should have found attr: #{the_attr} in schema, but only had: #{s.inspect}"
- + end
- + end
- +
- + test "with two instances, default schema should match the attributes of the individual instances - even if they differ" do
- + matz = Person.find(1)
- + rick = Person.find(5)
- +
- + m_attrs = matz.attributes.keys.sort
- + r_attrs = rick.attributes.keys.sort
- +
- + assert_not_equal m_attrs, r_attrs, "should have different attributes on each model"
- +
- + assert_not_equal matz.schema, rick.schema, "should have had different schemas too"
- + end
- +
- + test "defining a schema should return it when asked" do
- + assert Person.schema.blank?, "should have a blank class schema"
- + new_schema = [:name, :age, :height, :weight]
- + assert_nothing_raised {
- + Person.schema = new_schema
- + assert_equal new_schema, Person.schema, "should have saved the schema on the class"
- + assert_equal new_schema, Person.new.schema, "should have mde the schema available to every instance"
- + }
- +
- + Person.schema = nil # hack to stop test bleedthrough...
- + end
- +
- + test "defining a schema, then fetching a model should still match the defined schema" do
- + # sanity checks
- + assert Person.schema.blank?, "should have a blank class schema"
- + new_schema = [:name, :age, :height, :weight]
- +
- + matz = Person.find(1)
- + assert !matz.schema.blank?, "should have some sort of schema on an instance variable"
- + assert_not_equal new_schema, matz.schema, "should not have the class-level schema until it's been added to the class!"
- +
- + assert_nothing_raised {
- + Person.schema = new_schema
- + assert_equal new_schema, matz.schema, "class-level schema should override instance-level schema"
- + }
- +
- + Person.schema = nil # hack to stop test bleedthrough...
- + end
- +
- +end
- --
- 1.5.6.3
- From 3d2558e53c970dd572e1698aa00e8f83700b38b1 Mon Sep 17 00:00:00 2001
- From: Taryn East <git@taryneast.org>
- Date: Wed, 2 Dec 2009 21:53:13 +0000
- Subject: [PATCH] use schema to respond_to known 'columns' with true
- First actual functionality of a schema - respond_to? will recognise any
- schema attributes as valid methods.
- ---
- activeresource/lib/active_resource/base.rb | 2 ++
- activeresource/test/cases/base/schema_test.rb | 16 ++++++++++++++++
- 2 files changed, 18 insertions(+), 0 deletions(-)
- diff --git a/activeresource/lib/active_resource/base.rb b/activeresource/lib/active_resource/base.rb
- index b8aa028..294acba 100644
- --- a/activeresource/lib/active_resource/base.rb
- +++ b/activeresource/lib/active_resource/base.rb
- @@ -1175,6 +1175,8 @@ module ActiveResource
- super
- elsif attributes.has_key?(method_name)
- true
- + elsif schema && schema.include?(method_name.to_sym)
- + true
- elsif method_name =~ /(?:=|\?)$/ && attributes.include?($`)
- true
- else
- diff --git a/activeresource/test/cases/base/schema_test.rb b/activeresource/test/cases/base/schema_test.rb
- index 2fb2707..edd32e1 100644
- --- a/activeresource/test/cases/base/schema_test.rb
- +++ b/activeresource/test/cases/base/schema_test.rb
- @@ -112,4 +112,20 @@ class SchemaTest < ActiveModel::TestCase
- Person.schema = nil # hack to stop test bleedthrough...
- end
- + test "should respond to all attributes in a schema" do
- + assert Person.schema.blank?, "should have a blank class schema"
- + new_schema = [:name, :age, :height, :weight, :my_new_schema_attribute ]
- + p = Person.new
- + #sanity check - should not respond to the brand-new one
- + assert !p.respond_do?(:my_new_schema_attribute)
- +
- + assert_nothing_raised {
- + Person.schema = new_schema
- + new_schema.each do |the_attr|
- + assert Person.new.respond_to?(the_attr), "shoud respond to the schema's methods, but failed on: #{the_attr}"
- + end
- + }
- + Person.schema = nil # hack to stop test bleedthrough...
- + end
- +
- end
- --
- 1.5.6.3
- From d3a18363ef73d36192aa43abdb6b20590e7887e4 Mon Sep 17 00:00:00 2001
- From: Taryn East <git@taryneast.org>
- Date: Wed, 2 Dec 2009 22:06:43 +0000
- Subject: [PATCH] More documentation for schema to explain.
- Just a bit more commenting on what schema is and what it will do.
- ---
- activeresource/lib/active_resource/base.rb | 47 +++++++++++++++++++++++++--
- 1 files changed, 43 insertions(+), 4 deletions(-)
- diff --git a/activeresource/lib/active_resource/base.rb b/activeresource/lib/active_resource/base.rb
- index 294acba..f02e595 100644
- --- a/activeresource/lib/active_resource/base.rb
- +++ b/activeresource/lib/active_resource/base.rb
- @@ -243,13 +243,52 @@ module ActiveResource
- class << self
- # Schema defines the known attributes of the current model.
- #
- - # TODO: under construction - will add more doco as I go.
- - def schema=(the_schema)
- - @schema = the_schema
- - end
- + # The schema we pass into an Active Resource is similar to an Active
- + # Record database schema definition. It defines the known attributes
- + # of a certain Active Record - even if there are currently no values
- + # for those attributes. It is like telling Active Resource that you
- + # know there will be attributes there someday.
- + #
- + # There is no need to specify a schema for your Active Resource. If
- + # you do not, the schema will be automatically generated on an
- + # instance from the attributes found there. That kind of schema is
- + # transient and it is possible that each instance will have a
- + # different 'schema' of this sort.
- + #
- + # The benefits of knowing the schema in advance, is that your instance
- + # method will know that they can respond to the known attributes and
- + # will return 'nil' when questioned (instead of MethodNotFound). This
- + # is helpful if you wish to have validations on those attributes.
- + #
- + #
- + # This section is very much under construction. More documentaion will
- + # be added as the functionality is expanded.
- + #
- + #
- + # For the moment, all you can do is pass an array of known
- + # attribute-names and it will be saved on the Resource. See
- + # <tt>schema=</tt> for an example of how this works.
- + #
- + # In future, the Resource will be far more responsive eg will return
- + # 'true' for a known attribute or cast the value saved to the
- + # appropriate type - just as Active Record currently does.
- def schema
- @schema ||= nil
- end
- + # Saves a schema to this resource - telling it what attributes are
- + # already known prior to fetching an object of this type form the
- + # remote system.
- + #
- + # example:
- + # class Person < ActiveResource::Base
- + # schema = [:name, :age, :height, :weight]
- + # end
- + # p = Person.new
- + # p.respond_to? :name # > true
- + #
- + def schema=(the_schema)
- + @schema = the_schema
- + end
- # Gets the URI of the REST resources to map for this class. The site variable is required for
- # Active Resource's mapping to work.
- def site
- --
- 1.5.6.3
- From 5bde25dc25bc65510a6876299ce8d10e417ca544 Mon Sep 17 00:00:00 2001
- From: Taryn East <git@taryneast.org>
- Date: Wed, 2 Dec 2009 22:22:42 +0000
- Subject: [PATCH] return nil instead of MethodNotFound if in schema
- So this is why I wanted the schema all along - so that instead of exploding
- on a known attribute (simply because it hadn't been set yet) it should
- return nil - just like Active Record does.
- ---
- activeresource/lib/active_resource/base.rb | 4 ++-
- activeresource/test/cases/base/schema_test.rb | 33 +++++++++++++++++-------
- 2 files changed, 26 insertions(+), 11 deletions(-)
- diff --git a/activeresource/lib/active_resource/base.rb b/activeresource/lib/active_resource/base.rb
- index f02e595..b8134cd 100644
- --- a/activeresource/lib/active_resource/base.rb
- +++ b/activeresource/lib/active_resource/base.rb
- @@ -1319,7 +1319,9 @@ module ActiveResource
- attributes[$`]
- end
- else
- - attributes.include?(method_name) ? attributes[method_name] : super
- + return attributes[method_name] if attributes.include?(method_name)
- + return nil if self.class.schema.include?(method_symbol.to_sym)
- + super
- end
- end
- end
- diff --git a/activeresource/test/cases/base/schema_test.rb b/activeresource/test/cases/base/schema_test.rb
- index edd32e1..a3517d4 100644
- --- a/activeresource/test/cases/base/schema_test.rb
- +++ b/activeresource/test/cases/base/schema_test.rb
- @@ -112,20 +112,33 @@ class SchemaTest < ActiveModel::TestCase
- Person.schema = nil # hack to stop test bleedthrough...
- end
- - test "should respond to all attributes in a schema" do
- - assert Person.schema.blank?, "should have a blank class schema"
- - new_schema = [:name, :age, :height, :weight, :my_new_schema_attribute ]
- - p = Person.new
- - #sanity check - should not respond to the brand-new one
- - assert !p.respond_do?(:my_new_schema_attribute)
- + test "should respond positively to attributes only in a schema" do
- + new_attr_name = :my_new_schema_attribute
- + assert Person.schema.blank?, "sanity check - should have a blank class schema"
- +
- + assert !Person.new.respond_do?(new_attr_name), "sanity check - should not respond to the brand-new attribute yet"
- assert_nothing_raised {
- - Person.schema = new_schema
- - new_schema.each do |the_attr|
- - assert Person.new.respond_to?(the_attr), "shoud respond to the schema's methods, but failed on: #{the_attr}"
- - end
- + Person.schema = [new_attr_name]
- + assert Person.new.respond_to?(new_attr_name), "should respond to the schema's methods, but failed on: #{new_attr_name}"
- }
- Person.schema = nil # hack to stop test bleedthrough...
- end
- + test "should not give method_missing for attribute only in schema" do
- + new_attr_name = :another_new_schema_attribute
- +
- + assert Person.schema.blank?, "sanity check - should have a blank class schema"
- +
- + assert_raises(NoMethodError, "should not have found the attribute: #{new_attr_name} as a method") do
- + Person.new.send(new_attr_name)
- + end
- +
- + Person.schema = [new_attr_name]
- + assert_nothing_raised do
- + Person.new.send(new_attr_name)
- + end
- + Person.schema = nil # hack to stop test bleedthrough...
- + end
- +
- end
- --
- 1.5.6.3
- From 21e069cc4ef7b1240a6389b09d47f31e46fa8bfc Mon Sep 17 00:00:00 2001
- From: Taryn East <git@taryneast.org>
- Date: Wed, 2 Dec 2009 22:36:11 +0000
- Subject: [PATCH] Should symbolise schema keys to normalise
- Rather than hashes with indifferent access and all the inherant errors, we
- need to settle on either strings or symbols. I may change it all over to
- strings instead (as there seems to be a common theme in ARes for that), but
- for now - it's all symbols.
- ---
- activeresource/lib/active_resource/base.rb | 3 ++-
- activeresource/test/cases/base/schema_test.rb | 25 +++++++++++++++++++------
- 2 files changed, 21 insertions(+), 7 deletions(-)
- diff --git a/activeresource/lib/active_resource/base.rb b/activeresource/lib/active_resource/base.rb
- index b8134cd..a470a39 100644
- --- a/activeresource/lib/active_resource/base.rb
- +++ b/activeresource/lib/active_resource/base.rb
- @@ -287,7 +287,8 @@ module ActiveResource
- # p.respond_to? :name # > true
- #
- def schema=(the_schema)
- - @schema = the_schema
- + @schema = nil
- + @schema = the_schema.map(&:to_sym) if the_schema.present?
- end
- # Gets the URI of the REST resources to map for this class. The site variable is required for
- # Active Resource's mapping to work.
- diff --git a/activeresource/test/cases/base/schema_test.rb b/activeresource/test/cases/base/schema_test.rb
- index a3517d4..9d297b5 100644
- --- a/activeresource/test/cases/base/schema_test.rb
- +++ b/activeresource/test/cases/base/schema_test.rb
- @@ -54,12 +54,31 @@ class SchemaTest < ActiveModel::TestCase
- Person.user = nil
- Person.password = nil
- end
- + def teardown
- + Person.schema = nil # hack to stop test bleedthrough...
- + end
- test "schema on a new model should be empty" do
- assert Person.schema.blank?, "should have a blank class schema"
- assert Person.new.schema.blank?, "should have a blank instance schema"
- end
- + test "schema should accept array of syms" do
- + new_schema = [:age, :name]
- +
- + assert_nothing_raised { Person.schema = new_schema }
- + assert_equal new_schema, Person.schema
- + end
- +
- + test "schema should symbolise array of strings" do
- + new_schema = ['name', 'age']
- + new_schema_syms = new_schema.map(&:to_sym)
- +
- + assert_nothing_raised { Person.schema = new_schema }
- + assert_equal new_schema_syms, Person.schema
- + end
- +
- +
- test "schema on a found model should return all the attributes of that model instance" do
- p = Person.find(1)
- s = p.schema
- @@ -91,8 +110,6 @@ class SchemaTest < ActiveModel::TestCase
- assert_equal new_schema, Person.schema, "should have saved the schema on the class"
- assert_equal new_schema, Person.new.schema, "should have mde the schema available to every instance"
- }
- -
- - Person.schema = nil # hack to stop test bleedthrough...
- end
- test "defining a schema, then fetching a model should still match the defined schema" do
- @@ -108,8 +125,6 @@ class SchemaTest < ActiveModel::TestCase
- Person.schema = new_schema
- assert_equal new_schema, matz.schema, "class-level schema should override instance-level schema"
- }
- -
- - Person.schema = nil # hack to stop test bleedthrough...
- end
- test "should respond positively to attributes only in a schema" do
- @@ -122,7 +137,6 @@ class SchemaTest < ActiveModel::TestCase
- Person.schema = [new_attr_name]
- assert Person.new.respond_to?(new_attr_name), "should respond to the schema's methods, but failed on: #{new_attr_name}"
- }
- - Person.schema = nil # hack to stop test bleedthrough...
- end
- test "should not give method_missing for attribute only in schema" do
- @@ -138,7 +152,6 @@ class SchemaTest < ActiveModel::TestCase
- assert_nothing_raised do
- Person.new.send(new_attr_name)
- end
- - Person.schema = nil # hack to stop test bleedthrough...
- end
- end
- --
- 1.5.6.3
- From d67a56aea26e3993cdeec6b2d28b5a7ee46cd323 Mon Sep 17 00:00:00 2001
- From: taryneast <rubygirl@taryneast.org>
- Date: Tue, 8 Dec 2009 21:47:42 +0000
- Subject: [PATCH] Schema takes a hash, also added known_attributes
- Schema now takes a hash, which is one step closer to being actually useful.
- Right now it ignores the values of the hash, but that will start to be used
- in the next steps.
- Adding a schema now also populates a 'known_attributes' accessor - which
- takes over a lot of the functionality that I just had before - ie if we know
- about an attribute, we don't explode on method_missig, and we respond_to? it
- with true.
- known_attributes differs from attributes only in that it also recognises
- attributes from the schema.
- I also expanded on the comments/rdoc a little more.
- ---
- activeresource/lib/active_resource/base.rb | 88 +++++++++++++-------
- activeresource/test/cases/base/schema_test.rb | 111 ++++++++++++++++++++++---
- 2 files changed, 155 insertions(+), 44 deletions(-)
- diff --git a/activeresource/lib/active_resource/base.rb b/activeresource/lib/active_resource/base.rb
- index a470a39..3585f9d 100644
- --- a/activeresource/lib/active_resource/base.rb
- +++ b/activeresource/lib/active_resource/base.rb
- @@ -241,55 +241,74 @@ module ActiveResource
- cattr_accessor :logger
- class << self
- - # Schema defines the known attributes of the current model.
- + # Schema defines the known attributes of the current resource.
- #
- # The schema we pass into an Active Resource is similar to an Active
- - # Record database schema definition. It defines the known attributes
- - # of a certain Active Record - even if there are currently no values
- - # for those attributes. It is like telling Active Resource that you
- - # know there will be attributes there someday.
- + # Record database migration. It defines the known attributes of the
- + # Resource - even if there are currently no values for those
- + # attributes. It is like telling Active Resource that you know there
- + # will be attributes there someday.
- #
- # There is no need to specify a schema for your Active Resource. If
- - # you do not, the schema will be automatically generated on an
- - # instance from the attributes found there. That kind of schema is
- - # transient and it is possible that each instance will have a
- - # different 'schema' of this sort.
- + # you do not, the schema will be guessed from the instance attributes
- + # returned when the instance is fetched from the remote system (as
- + # before). The guessed schema is transient and it is possible that
- + # each instance will have a different 'schema' of this sort.
- #
- - # The benefits of knowing the schema in advance, is that your instance
- - # method will know that they can respond to the known attributes and
- - # will return 'nil' when questioned (instead of MethodNotFound). This
- - # is helpful if you wish to have validations on those attributes.
- + # The benefit of knowing the schema in advance is that your instance
- + # method will know that they can <tt>respond_to></tt> the known
- + # attributes and will return 'nil' when questioned (instead of
- + # MethodNotFound). This is helpful if you wish to have validations on
- + # those attributes (eg <tt>validates_presence_of</tt>)
- #
- #
- # This section is very much under construction. More documentaion will
- # be added as the functionality is expanded.
- #
- #
- - # For the moment, all you can do is pass an array of known
- - # attribute-names and it will be saved on the Resource. See
- - # <tt>schema=</tt> for an example of how this works.
- + # For the moment, all you can do is pass a hash of known
- + # attribute-names with any values and it will be saved on the
- + # Resource. See <tt>schema=</tt> for an example of how this works.
- #
- - # In future, the Resource will be far more responsive eg will return
- - # 'true' for a known attribute or cast the value saved to the
- - # appropriate type - just as Active Record currently does.
- + # The attribute-names are also saved into the Resource's
- + # <tt>known_attributes</tt>
- + #
- + # In future, the Resource will be far more responsive eg will cast the
- + # attribute's value saved to the appropriate type - just as Active
- + # Record currently does.
- def schema
- @schema ||= nil
- end
- - # Saves a schema to this resource - telling it what attributes are
- - # already known prior to fetching an object of this type form the
- - # remote system.
- +
- + # Saves a schema to this resource - setting the attributes that are
- + # known prior to fetching an instance from the remote system.
- #
- # example:
- # class Person < ActiveResource::Base
- - # schema = [:name, :age, :height, :weight]
- + # schema = {:name => :string, :age => :integer,
- + # :height => :float, :weight => :float }
- # end
- # p = Person.new
- - # p.respond_to? :name # > true
- - #
- + # p.respond_to? :name # => true
- + # p.name # => nil
- + #
- def schema=(the_schema)
- @schema = nil
- - @schema = the_schema.map(&:to_sym) if the_schema.present?
- + @known_attributes = []
- + return unless the_schema.present?
- +
- + raise ArgumentError, "Expected a hash" unless the_schema.kind_of? Hash
- +
- + @schema = the_schema.with_indifferent_access
- + @known_attributes = the_schema.keys.map(&:to_s)
- + end
- +
- + # Returns the list of known attributes for this resource, gathered
- + # from the provided <tt>schema</tt>
- + def known_attributes
- + @known_attributes ||= []
- end
- +
- # Gets the URI of the REST resources to map for this class. The site variable is required for
- # Active Resource's mapping to work.
- def site
- @@ -829,9 +848,17 @@ module ActiveResource
- # <tt>ActiveResource::schema=</tt>), the default automatic schema is
- # generated from the current instance's attributes
- def schema
- - self.class.schema || self.attributes.keys
- + self.class.schema || self.attributes
- + end
- +
- + # This is a list of known attributes for this resource. Either
- + # gathered fromthe provided <tt>schema</tt>, or from the attributes
- + # set on this instance after it has been fetched from the remote system.
- + def known_attributes
- + self.class.known_attributes + self.attributes.keys.map(&:to_s)
- end
- +
- # Constructor method for \new resources; the optional +attributes+ parameter takes a \hash
- # of attributes for the \new resource.
- #
- @@ -1213,9 +1240,7 @@ module ActiveResource
- method_name = method.to_s
- if attributes.nil?
- super
- - elsif attributes.has_key?(method_name)
- - true
- - elsif schema && schema.include?(method_name.to_sym)
- + elsif known_attributes.include?(method_name)
- true
- elsif method_name =~ /(?:=|\?)$/ && attributes.include?($`)
- true
- @@ -1321,7 +1346,8 @@ module ActiveResource
- end
- else
- return attributes[method_name] if attributes.include?(method_name)
- - return nil if self.class.schema.include?(method_symbol.to_sym)
- + # not set right now but we know about it
- + return nil if known_attributes.include?(method_name)
- super
- end
- end
- diff --git a/activeresource/test/cases/base/schema_test.rb b/activeresource/test/cases/base/schema_test.rb
- index 9d297b5..a8e9bc8 100644
- --- a/activeresource/test/cases/base/schema_test.rb
- +++ b/activeresource/test/cases/base/schema_test.rb
- @@ -63,30 +63,52 @@ class SchemaTest < ActiveModel::TestCase
- assert Person.new.schema.blank?, "should have a blank instance schema"
- end
- - test "schema should accept array of syms" do
- - new_schema = [:age, :name]
- + test "schema should only accept a hash" do
- + ["blahblah",['one','two'], [:age, :name]].each do |bad_schema|
- + assert_raises(ArgumentError,"should only accept a hash, but accepted: #{bad_schema.inspect}") do
- + Person.schema = bad_schema
- + end
- + end
- + end
- +
- + test "schema should accept a simple hash" do
- + new_schema = {'age' => nil, 'name' => nil}
- assert_nothing_raised { Person.schema = new_schema }
- assert_equal new_schema, Person.schema
- end
- - test "schema should symbolise array of strings" do
- - new_schema = ['name', 'age']
- - new_schema_syms = new_schema.map(&:to_sym)
- + test "schema should accept nil and remove the schema" do
- + new_schema = {'age' => nil, 'name' => nil}
- + assert_nothing_raised { Person.schema = new_schema }
- + assert_equal new_schema, Person.schema # sanity check
- +
- +
- + assert_nothing_raised { Person.schema = nil }
- + assert_nil Person.schema, "should have nulled out the schema, but still had: #{Person.schema.inspect}"
- + end
- +
- +
- + test "schema should be with indifferent access" do
- + new_schema = {:age => nil, 'name' => nil}
- + new_schema_syms = new_schema.keys
- assert_nothing_raised { Person.schema = new_schema }
- - assert_equal new_schema_syms, Person.schema
- + new_schema_syms.each do |col|
- + assert Person.new.respond_to?(col.to_s), "should respond to the schema's string key, but failed on: #{col.to_s}"
- + assert Person.new.respond_to?(col.to_sym), "should respond to the schema's symbol key, but failed on: #{col.to_sym}"
- + end
- end
- - test "schema on a found model should return all the attributes of that model instance" do
- + test "schema on a fetched resource should return all the attributes of that model instance" do
- p = Person.find(1)
- s = p.schema
- assert s.present?, "should have found a non-empty schema!"
- p.attributes.each do |the_attr, val|
- - assert s.include?(the_attr), "should have found attr: #{the_attr} in schema, but only had: #{s.inspect}"
- + assert s.has_key?(the_attr), "should have found attr: #{the_attr} in schema, but only had: #{s.inspect}"
- end
- end
- @@ -104,7 +126,7 @@ class SchemaTest < ActiveModel::TestCase
- test "defining a schema should return it when asked" do
- assert Person.schema.blank?, "should have a blank class schema"
- - new_schema = [:name, :age, :height, :weight]
- + new_schema = {'name' => nil, 'age' => nil, 'height' => nil, 'weight' => nil}
- assert_nothing_raised {
- Person.schema = new_schema
- assert_equal new_schema, Person.schema, "should have saved the schema on the class"
- @@ -115,7 +137,7 @@ class SchemaTest < ActiveModel::TestCase
- test "defining a schema, then fetching a model should still match the defined schema" do
- # sanity checks
- assert Person.schema.blank?, "should have a blank class schema"
- - new_schema = [:name, :age, :height, :weight]
- + new_schema = {'name' => nil, 'age' => nil, 'height' => nil, 'weight' => nil}
- matz = Person.find(1)
- assert !matz.schema.blank?, "should have some sort of schema on an instance variable"
- @@ -127,14 +149,14 @@ class SchemaTest < ActiveModel::TestCase
- }
- end
- - test "should respond positively to attributes only in a schema" do
- + test "should respond positively to attributes that are only in the schema" do
- new_attr_name = :my_new_schema_attribute
- assert Person.schema.blank?, "sanity check - should have a blank class schema"
- assert !Person.new.respond_do?(new_attr_name), "sanity check - should not respond to the brand-new attribute yet"
- assert_nothing_raised {
- - Person.schema = [new_attr_name]
- + Person.schema = {new_attr_name.to_s => nil}
- assert Person.new.respond_to?(new_attr_name), "should respond to the schema's methods, but failed on: #{new_attr_name}"
- }
- end
- @@ -148,10 +170,73 @@ class SchemaTest < ActiveModel::TestCase
- Person.new.send(new_attr_name)
- end
- - Person.schema = [new_attr_name]
- + Person.schema = {new_attr_name.to_s => nil}
- assert_nothing_raised do
- Person.new.send(new_attr_name)
- end
- end
- +
- + #####################################################
- + # Known attributes
- + #
- + # Attributes can be known even if they aren't actually 'set' on a
- + # particular instance.
- + # This will only differ from 'attributes' if a schema has been set.
- +
- + test "new model should have no known attributes" do
- + assert Person.known_attributes.blank?, "should have no known attributes"
- + assert Person.new.known_attributes.blank?, "should have no known attributes on a new instance"
- + end
- +
- + test "setting schema should set known attributes on class and instance" do
- + new_schema = {'age' => nil, 'name' => nil}
- +
- + assert_nothing_raised { Person.schema = new_schema }
- +
- + assert_equal new_schema.keys, Person.known_attributes
- + assert_equal new_schema.keys, Person.new.known_attributes
- + end
- +
- + test "known attributes on a fetched resource should return all the attributes of the instance" do
- + p = Person.find(1)
- + attrs = p.known_attributes
- +
- + assert attrs.present?, "should have found some attributes!"
- +
- + p.attributes.each do |the_attr, val|
- + assert attrs.include?(the_attr), "should have found attr: #{the_attr} in known attributes, but only had: #{attrs.inspect}"
- + end
- + end
- +
- + test "with two instances, known attributes should match the attributes of the individual instances - even if they differ" do
- + matz = Person.find(1)
- + rick = Person.find(5)
- +
- + m_attrs = matz.attributes.keys.sort
- + r_attrs = rick.attributes.keys.sort
- +
- + assert_not_equal m_attrs, r_attrs, "should have different attributes on each model"
- +
- + assert_not_equal matz.known_attributes, rick.known_attributes, "should have had different known attributes too"
- + end
- +
- + test "setting schema then fetching should add schema attributes to the intance attributes" do
- + # an attribute in common with fetched instance and one that isn't
- + new_schema = {'name' => nil, 'my_strange_attribute' => nil}
- +
- + assert_nothing_raised { Person.schema = new_schema }
- +
- + matz = Person.find(1)
- + known_attrs = matz.known_attributes
- +
- + matz.attributes.keys.each do |the_attr|
- + assert known_attrs.include?(the_attr), "should have found instance attr: #{the_attr} in known attributes, but only had: #{known_attrs.inspect}"
- + end
- + new_schema.keys.each do |the_attr|
- + assert known_attrs.include?(the_attr), "should have found schema attr: #{the_attr} in known attributes, but only had: #{known_attrs.inspect}"
- + end
- + end
- +
- +
- end
- --
- 1.5.6.3
- From ee5da75e80abeaa26ca1267f08d2d4f5ce30edbf Mon Sep 17 00:00:00 2001
- From: taryneast <rubygirl@taryneast.org>
- Date: Tue, 8 Dec 2009 21:52:36 +0000
- Subject: [PATCH] Clear the schema/known_attrs only if passed nil
- I'll be adding in more argument-checking shortly. I don't want to clear the
- schema only to find that the given new schema is wrong. So I'll enclose the
- schema-nullification section and only do it if we've specificaly requested
- it.
- ---
- activeresource/lib/active_resource/base.rb | 8 +++++---
- 1 files changed, 5 insertions(+), 3 deletions(-)
- diff --git a/activeresource/lib/active_resource/base.rb b/activeresource/lib/active_resource/base.rb
- index 3585f9d..2c47849 100644
- --- a/activeresource/lib/active_resource/base.rb
- +++ b/activeresource/lib/active_resource/base.rb
- @@ -293,9 +293,11 @@ module ActiveResource
- # p.name # => nil
- #
- def schema=(the_schema)
- - @schema = nil
- - @known_attributes = []
- - return unless the_schema.present?
- + unless the_schema.present?
- + @schema = nil
- + @known_attributes = []
- + return
- + end
- raise ArgumentError, "Expected a hash" unless the_schema.kind_of? Hash
- --
- 1.5.6.3
- From 3d4e69210ff7adca7bfa861bf211b7e24d0b26fe Mon Sep 17 00:00:00 2001
- From: taryneast <rubygirl@taryneast.org>
- Date: Fri, 11 Dec 2009 20:30:22 +0000
- Subject: [PATCH] Updates to coments
- Better explanation for the current state of the schema - how to use it, and
- where it's going shortly.
- ---
- activeresource/lib/active_resource/base.rb | 76 ++++++++++++------------
- activeresource/test/cases/base/schema_test.rb | 6 +-
- 2 files changed, 41 insertions(+), 41 deletions(-)
- diff --git a/activeresource/lib/active_resource/base.rb b/activeresource/lib/active_resource/base.rb
- index 2c47849..73a0ecb 100644
- --- a/activeresource/lib/active_resource/base.rb
- +++ b/activeresource/lib/active_resource/base.rb
- @@ -241,56 +241,51 @@ module ActiveResource
- cattr_accessor :logger
- class << self
- - # Schema defines the known attributes of the current resource.
- - #
- - # The schema we pass into an Active Resource is similar to an Active
- - # Record database migration. It defines the known attributes of the
- - # Resource - even if there are currently no values for those
- - # attributes. It is like telling Active Resource that you know there
- - # will be attributes there someday.
- - #
- - # There is no need to specify a schema for your Active Resource. If
- - # you do not, the schema will be guessed from the instance attributes
- - # returned when the instance is fetched from the remote system (as
- - # before). The guessed schema is transient and it is possible that
- - # each instance will have a different 'schema' of this sort.
- - #
- - # The benefit of knowing the schema in advance is that your instance
- - # method will know that they can <tt>respond_to></tt> the known
- - # attributes and will return 'nil' when questioned (instead of
- - # MethodNotFound). This is helpful if you wish to have validations on
- - # those attributes (eg <tt>validates_presence_of</tt>)
- - #
- - #
- - # This section is very much under construction. More documentaion will
- - # be added as the functionality is expanded.
- - #
- - #
- - # For the moment, all you can do is pass a hash of known
- - # attribute-names with any values and it will be saved on the
- - # Resource. See <tt>schema=</tt> for an example of how this works.
- - #
- - # The attribute-names are also saved into the Resource's
- - # <tt>known_attributes</tt>
- - #
- - # In future, the Resource will be far more responsive eg will cast the
- - # attribute's value saved to the appropriate type - just as Active
- - # Record currently does.
- - def schema
- + # This will shortly disappear to be replaced by the migration-style
- + # usage of this for defining a schema. At that point, all the doc
- + # currenlty on <tt>schema=</tt> will move back here...
- + def schema # :nodoc:
- @schema ||= nil
- end
- # Saves a schema to this resource - setting the attributes that are
- # known prior to fetching an instance from the remote system.
- #
- + # The schema helps define the set of <tt>known_attributes</tt> of the
- + # current resource.
- + #
- + # There is no need to specify a schema for your Active Resource. If
- + # you do not, the <tt>known_attributes</tt> will be guessed from the
- + # instance attributes returned when an instance is fetched from the
- + # remote system.
- + #
- # example:
- # class Person < ActiveResource::Base
- - # schema = {:name => :string, :age => :integer,
- - # :height => :float, :weight => :float }
- + # schema = {:name => :string, :age => :integer }
- # end
- # p = Person.new
- # p.respond_to? :name # => true
- + # p.respond_to? :age # => true
- # p.name # => nil
- + # p.age # => nil
- + #
- + # j = Person.find_by_name('John') # <person><name>John</name><age>34</age><weight>65</weight></person>
- + # j.respond_to? :name # => true
- + # j.respond_to? :age # => true
- + # j.name # => 'John'
- + # j.age # => '34' # note this is a string!
- + # j.weight # => '65' # note this is a string!
- + #
- + # p.weight # => MethodNotFound
- + #
- + # The schema must be a hash with the key being the attribute's name,
- + # and the value being the attribute type.
- + #
- + # Note: at present the value doesn't do anything, but stay tuned...
- + # Shortly it will also *cast* the value of the returned attribute.
- + # ie:
- + # j.age # => 34 # cast to an integer
- + # j.weight # => '65' # still a string!
- #
- def schema=(the_schema)
- unless the_schema.present?
- @@ -307,6 +302,11 @@ module ActiveResource
- # Returns the list of known attributes for this resource, gathered
- # from the provided <tt>schema</tt>
- + # Attributes that are known will cause your resource to return 'true'
- + # when <tt>respond_to?</tt> is called on them. A known attribute will
- + # return nil if not set (rather than <t>MethodNotFound</tt>); thus
- + # known attributes can be used with <tt>validates_presence_of</tt>
- + # without a getter-method.
- def known_attributes
- @known_attributes ||= []
- end
- diff --git a/activeresource/test/cases/base/schema_test.rb b/activeresource/test/cases/base/schema_test.rb
- index a8e9bc8..5374ce0 100644
- --- a/activeresource/test/cases/base/schema_test.rb
- +++ b/activeresource/test/cases/base/schema_test.rb
- @@ -180,9 +180,9 @@ class SchemaTest < ActiveModel::TestCase
- #####################################################
- # Known attributes
- #
- - # Attributes can be known even if they aren't actually 'set' on a
- - # particular instance.
- - # This will only differ from 'attributes' if a schema has been set.
- + # Attributes can be known to be attributes even if they aren't actually
- + # 'set' on a particular instance.
- + # This will only differ from 'attributes' if a schema has been set.
- test "new model should have no known attributes" do
- assert Person.known_attributes.blank?, "should have no known attributes"
- --
- 1.5.6.3
- From c3e811746f52a0a47eda51aae6864d1809448e02 Mon Sep 17 00:00:00 2001
- From: taryneast <rubygirl@taryneast.org>
- Date: Fri, 11 Dec 2009 21:33:17 +0000
- Subject: [PATCH] schema values must be part of known set.
- I've added a limited set of known values for schema attributes.
- Anything that doesn't match that set is rejected.
- Currently I'm starting with [:string, :integer, :float] because those will
- be easy to typecast-to, which is my next step.
- ---
- activeresource/lib/active_resource/base.rb | 25 +++++++++++++++++++--
- activeresource/test/cases/base/schema_test.rb | 28 +++++++++++++++++++++++-
- 2 files changed, 48 insertions(+), 5 deletions(-)
- diff --git a/activeresource/lib/active_resource/base.rb b/activeresource/lib/active_resource/base.rb
- index 73a0ecb..9d3e8b6 100644
- --- a/activeresource/lib/active_resource/base.rb
- +++ b/activeresource/lib/active_resource/base.rb
- @@ -248,6 +248,10 @@ module ActiveResource
- @schema ||= nil
- end
- + # attributes can be known to be one of these types. They are easy to
- + # cast to/from.
- + KNOWN_ATTRIBUTE_TYPES = [:string, :integer, :float]
- +
- # Saves a schema to this resource - setting the attributes that are
- # known prior to fetching an instance from the remote system.
- #
- @@ -261,7 +265,7 @@ module ActiveResource
- #
- # example:
- # class Person < ActiveResource::Base
- - # schema = {:name => :string, :age => :integer }
- + # schema = {'name' => :string, 'age' => :integer }
- # end
- # p = Person.new
- # p.respond_to? :name # => true
- @@ -278,8 +282,19 @@ module ActiveResource
- #
- # p.weight # => MethodNotFound
- #
- - # The schema must be a hash with the key being the attribute's name,
- - # and the value being the attribute type.
- + # The schema must be a hash with the *string* key being the
- + # attribute's name, and the value being the attribute type.
- + #
- + # Attribute-types must be one of:
- + # :string, :integer, :float
- + #
- + # Attributes will be typecast into the type you give it (the original
- + # will still be available through <tt>attribute_before_typecast(:the_attr_name)</tt>
- + #
- + # If an attribute does not have a type, it will not be typecast
- + #
- + # Note: date/times aren't yet supported... the best option is to leave
- + # them as strings and cast them appropriately in your own code.
- #
- # Note: at present the value doesn't do anything, but stay tuned...
- # Shortly it will also *cast* the value of the returned attribute.
- @@ -296,6 +311,10 @@ module ActiveResource
- raise ArgumentError, "Expected a hash" unless the_schema.kind_of? Hash
- + the_schema.each do |k,v|
- + raise ArgumentError, "Unknown attribute type: #{v.inspect} for key: #{k.inspect}" unless v.nil? || KNOWN_ATTRIBUTE_TYPES.include?(v.to_sym)
- + end
- +
- @schema = the_schema.with_indifferent_access
- @known_attributes = the_schema.keys.map(&:to_s)
- end
- diff --git a/activeresource/test/cases/base/schema_test.rb b/activeresource/test/cases/base/schema_test.rb
- index 5374ce0..7c5066c 100644
- --- a/activeresource/test/cases/base/schema_test.rb
- +++ b/activeresource/test/cases/base/schema_test.rb
- @@ -64,8 +64,8 @@ class SchemaTest < ActiveModel::TestCase
- end
- test "schema should only accept a hash" do
- - ["blahblah",['one','two'], [:age, :name]].each do |bad_schema|
- - assert_raises(ArgumentError,"should only accept a hash, but accepted: #{bad_schema.inspect}") do
- + ["blahblah", ['one','two'], [:age, :name], Person.new].each do |bad_schema|
- + assert_raises(ArgumentError,"should only accept a hash (or nil), but accepted: #{bad_schema.inspect}") do
- Person.schema = bad_schema
- end
- end
- @@ -78,6 +78,30 @@ class SchemaTest < ActiveModel::TestCase
- assert_equal new_schema, Person.schema
- end
- + test "schema should accept a hash with simple values" do
- + new_schema = {'age' => :integer, 'name' => :string, 'height' => :float, 'mydatetime' => nil}
- +
- + assert_nothing_raised { Person.schema = new_schema }
- + assert_equal new_schema, Person.schema
- + end
- +
- + test "schema should accept all known attribute types as values" do
- + # I'd prefer to use ActiveResource::KNOWN_ATTRIBUTE_TYPES here...
- + [:string, :integer, :float].each do |the_type|
- + assert_nothing_raised("should have accepted #{the_type.inspect}"){ Person.schema = {'my_key' => the_type }}
- + end
- + end
- +
- + test "schema should not accept unknown values" do
- + bad_values = [ :oogle, :blob, 'thing']
- +
- + bad_values.each do |bad_value|
- + assert_raises(ArgumentError,"should only accept a known attribute type, but accepted: #{bad_value.inspect}") do
- + Person.schema = {'key' => bad_value}
- + end
- + end
- + end
- +
- test "schema should accept nil and remove the schema" do
- new_schema = {'age' => nil, 'name' => nil}
- assert_nothing_raised { Person.schema = new_schema }
- --
- 1.5.6.3
- From c83d9b5e379bea4234d82efa1797a316ee494f61 Mon Sep 17 00:00:00 2001
- From: taryneast <rubygirl@taryneast.org>
- Date: Sat, 12 Dec 2009 12:36:33 +0000
- Subject: [PATCH] First attempt at Migration-style SchemaDefinition
- Very basic and probably broken. It's also pre-test-building.
- I'll get it working and matched into tests next.
- ---
- activeresource/lib/active_resource/base.rb | 5 ++
- .../lib/active_resource/schema_definition.rb | 41 ++++++++++++++++++++
- 2 files changed, 46 insertions(+), 0 deletions(-)
- create mode 100644 activeresource/lib/active_resource/schema_definition.rb
- diff --git a/activeresource/lib/active_resource/base.rb b/activeresource/lib/active_resource/base.rb
- index 9d3e8b6..dac641e 100644
- --- a/activeresource/lib/active_resource/base.rb
- +++ b/activeresource/lib/active_resource/base.rb
- @@ -247,6 +247,11 @@ module ActiveResource
- def schema # :nodoc:
- @schema ||= nil
- end
- + # def schema
- + # schema_definition = SchemaDefinition.new
- + # yield schema_definition if block_given?
- + # # do stuff with what's int he schema def attrs
- + # end
- # attributes can be known to be one of these types. They are easy to
- # cast to/from.
- diff --git a/activeresource/lib/active_resource/schema_definition.rb b/activeresource/lib/active_resource/schema_definition.rb
- new file mode 100644
- index 0000000..0a635c2
- --- /dev/null
- +++ b/activeresource/lib/active_resource/schema_definition.rb
- @@ -0,0 +1,41 @@
- +require 'active_resource/exceptions'
- +
- +module ActiveResource
- + class SchemaDefinition
- + # An array of attribute definitions, representing the attributes that
- + # have been defined.
- + attr_accessor :attrs
- +
- + def initialize(base)
- + @attrs = []
- + end
- +
- + # Returns an attribute definition for the attribute with name +name+.
- + def [](name)
- + @attrs[name.to_s]
- + end
- +
- + def attribute(name, type, options = {})
- + the_attr = [type.to_s]
- + the_attr << options[:default] if options.hs_key? :default
- + @attrs[name.to_s] = the_attr
- + self
- + end
- +
- + # The following are he attribute types supported by Active Record
- + # migra5tions. We should eventually support all of these
- + # %w( string text integer float decimal datetime timestamp time date binary boolean ).each do |attr_type|
- + %w( string integer float ).each do |attr_type|
- + class_eval <<-EOV
- + def #{attr_type}(*args) # def string(*args)
- + options = args.extract_options! # options = args.extract_options!
- + attr_names = args # attr_names = args
- + #
- + attr_names.each { |name| attribute(name, '#{attr_type}', options) } # attr_names.each { |name| attribute(name, 'string', options) }
- + end # end
- + EOV
- + end
- +
- +
- + end
- +end
- --
- 1.5.6.3
- From eff61e3ef3aca5ec37556f13f3b5cc7872f27b66 Mon Sep 17 00:00:00 2001
- From: taryneast <rubygirl@taryneast.org>
- Date: Mon, 14 Dec 2009 18:54:09 +0000
- Subject: [PATCH] Just comments in tests.
- To split the tests into logical blocks of things we're testing for - and
- make it easy for me to find them again.
- ---
- activeresource/test/cases/base/schema_test.rb | 14 +++++++++++++-
- 1 files changed, 13 insertions(+), 1 deletions(-)
- diff --git a/activeresource/test/cases/base/schema_test.rb b/activeresource/test/cases/base/schema_test.rb
- index 7c5066c..c8b9864 100644
- --- a/activeresource/test/cases/base/schema_test.rb
- +++ b/activeresource/test/cases/base/schema_test.rb
- @@ -58,6 +58,11 @@ class SchemaTest < ActiveModel::TestCase
- Person.schema = nil # hack to stop test bleedthrough...
- end
- +
- + #####################################################
- + # Passing in a schema directly and returning it
- + ####
- +
- test "schema on a new model should be empty" do
- assert Person.schema.blank?, "should have a blank class schema"
- assert Person.new.schema.blank?, "should have a blank instance schema"
- @@ -173,6 +178,13 @@ class SchemaTest < ActiveModel::TestCase
- }
- end
- +
- + #####################################################
- + # What a schema does for us
- + ####
- +
- + # respond_to? and method_missing effects
- +
- test "should respond positively to attributes that are only in the schema" do
- new_attr_name = :my_new_schema_attribute
- assert Person.schema.blank?, "sanity check - should have a blank class schema"
- @@ -201,7 +213,7 @@ class SchemaTest < ActiveModel::TestCase
- end
- - #####################################################
- + ########
- # Known attributes
- #
- # Attributes can be known to be attributes even if they aren't actually
- --
- 1.5.6.3
- From 9334d74f6ea491ca2f28e01614b748ebb73d84b4 Mon Sep 17 00:00:00 2001
- From: taryneast <rubygirl@taryneast.org>
- Date: Mon, 14 Dec 2009 19:46:27 +0000
- Subject: [PATCH] The basics of ActiveResource.define_schema syntax
- For now it is very simple. The SchemaDefinition roughly follows the lines of
- an ActiveRecord TableDefinition from migrations.
- At present all it does is store a set of attributes onto itself.
- ---
- activeresource/lib/active_resource/base.rb | 12 +++--
- .../lib/active_resource/schema_definition.rb | 46 +++++++++-----------
- activeresource/test/cases/base/schema_test.rb | 44 +++++++++++++++++++
- 3 files changed, 72 insertions(+), 30 deletions(-)
- diff --git a/activeresource/lib/active_resource/base.rb b/activeresource/lib/active_resource/base.rb
- index dac641e..fee6a53 100644
- --- a/activeresource/lib/active_resource/base.rb
- +++ b/activeresource/lib/active_resource/base.rb
- @@ -13,6 +13,7 @@ require 'set'
- require 'uri'
- require 'active_resource/exceptions'
- +require 'active_resource/schema_definition'
- module ActiveResource
- # ActiveResource::Base is the main class for mapping RESTful resources as models in a Rails application.
- @@ -247,11 +248,12 @@ module ActiveResource
- def schema # :nodoc:
- @schema ||= nil
- end
- - # def schema
- - # schema_definition = SchemaDefinition.new
- - # yield schema_definition if block_given?
- - # # do stuff with what's int he schema def attrs
- - # end
- +
- + def define_schema
- + schema_definition = SchemaDefinition.new
- + yield schema_definition if block_given?
- + # do stuff with what's in the schema def attrs
- + end
- # attributes can be known to be one of these types. They are easy to
- # cast to/from.
- diff --git a/activeresource/lib/active_resource/schema_definition.rb b/activeresource/lib/active_resource/schema_definition.rb
- index 0a635c2..0f1cfd6 100644
- --- a/activeresource/lib/active_resource/schema_definition.rb
- +++ b/activeresource/lib/active_resource/schema_definition.rb
- @@ -1,41 +1,37 @@
- require 'active_resource/exceptions'
- -module ActiveResource
- - class SchemaDefinition
- +module ActiveResource # :nodoc:
- + class SchemaDefinition # :nodoc:
- +
- # An array of attribute definitions, representing the attributes that
- # have been defined.
- attr_accessor :attrs
- - def initialize(base)
- - @attrs = []
- - end
- -
- - # Returns an attribute definition for the attribute with name +name+.
- - def [](name)
- - @attrs[name.to_s]
- + # The internals of an Active Resource SchemaDefinition are very simple -
- + # unlike an Active Record TableDefinition (on which it is based).
- + # It provides a set of convenience methods for people to define their
- + # schema using the syntax:
- + # define_schema do |s|
- + # s.string :foo
- + # s.integer :bar
- + # end
- + #
- + # The schema stores the name and type of each attribute. That is then
- + # read out by the define_schema method to populate the actual
- + # Resource's schema
- + def initialize
- + @attrs = {}
- end
- def attribute(name, type, options = {})
- - the_attr = [type.to_s]
- - the_attr << options[:default] if options.hs_key? :default
- + the_attr = type.to_s
- + # TODO: add defaults
- + #the_attr = [type.to_s]
- + #the_attr << options[:default] if options.has_key? :default
- @attrs[name.to_s] = the_attr
- self
- end
- - # The following are he attribute types supported by Active Record
- - # migra5tions. We should eventually support all of these
- - # %w( string text integer float decimal datetime timestamp time date binary boolean ).each do |attr_type|
- - %w( string integer float ).each do |attr_type|
- - class_eval <<-EOV
- - def #{attr_type}(*args) # def string(*args)
- - options = args.extract_options! # options = args.extract_options!
- - attr_names = args # attr_names = args
- - #
- - attr_names.each { |name| attribute(name, '#{attr_type}', options) } # attr_names.each { |name| attribute(name, 'string', options) }
- - end # end
- - EOV
- - end
- -
- end
- end
- diff --git a/activeresource/test/cases/base/schema_test.rb b/activeresource/test/cases/base/schema_test.rb
- index c8b9864..6e659fb 100644
- --- a/activeresource/test/cases/base/schema_test.rb
- +++ b/activeresource/test/cases/base/schema_test.rb
- @@ -177,7 +177,51 @@ class SchemaTest < ActiveModel::TestCase
- assert_equal new_schema, matz.schema, "class-level schema should override instance-level schema"
- }
- end
- +
- +
- + #####################################################
- + # Using the define_schema syntax
- + ####
- +
- + test "should be able to use define_schema" do
- + assert Person.respond_to?(:define_schema), "should at least respond to the define_schema method"
- +
- + assert_nothing_raised("Should allow the define_schema to take a block") do
- + Person.define_schema do |s|
- + assert s.kind_of?(ActiveResource::SchemaDefinition), "the 's' should be a schema definition or we're way off track..."
- + end
- + end
- + end
- +
- + test "should be able to add attributes through define_schema" do
- + assert_nothing_raised do
- + Person.define_schema do |s|
- + assert s.attribute('foo', 'string'), "should take a simple attribute"
- + assert s.attrs.has_key?('foo'), "should have saved the attribute name"
- + assert_equal 'string', s.attrs['foo'], "should have saved the attribute type"
- + end
- + end
- + end
- + test "should convert symbol attributes to strings" do
- + assert_nothing_raised do
- + Person.define_schema do |s|
- + assert s.attribute(:foo, :integer), "should take a simple attribute as symbols"
- + assert s.attrs.has_key?('foo'), "should have saved the attribute name as a string"
- + assert_equal 'integer', s.attrs['foo'], "should have saved the attribute type as a string"
- + end
- + end
- + end
- +
- + test "schema definition should store and return attributes" do
- + assert_nothing_raised do
- + Person.define_schema do |s|
- + assert s.respond_to?(:attrs), "should return attributes in theory"
- + s.attribute :foo, :string
- + assert_equal({'foo' => 'string' }, s.attrs, "should return attributes in practice")
- + end
- + end
- + end
- #####################################################
- # What a schema does for us
- --
- 1.5.6.3
- From db54df24f33664da0ba17fff5d5d30e4c87f69a9 Mon Sep 17 00:00:00 2001
- From: taryneast <rubygirl@taryneast.org>
- Date: Mon, 14 Dec 2009 19:54:46 +0000
- Subject: [PATCH] Moved 'known_atribute_types' into SchemaDefinition
- where they really belong.
- ---
- activeresource/lib/active_resource/base.rb | 5 +----
- .../lib/active_resource/schema_definition.rb | 5 ++++-
- activeresource/test/cases/base/schema_test.rb | 4 ++--
- 3 files changed, 7 insertions(+), 7 deletions(-)
- diff --git a/activeresource/lib/active_resource/base.rb b/activeresource/lib/active_resource/base.rb
- index fee6a53..c713889 100644
- --- a/activeresource/lib/active_resource/base.rb
- +++ b/activeresource/lib/active_resource/base.rb
- @@ -255,9 +255,6 @@ module ActiveResource
- # do stuff with what's in the schema def attrs
- end
- - # attributes can be known to be one of these types. They are easy to
- - # cast to/from.
- - KNOWN_ATTRIBUTE_TYPES = [:string, :integer, :float]
- # Saves a schema to this resource - setting the attributes that are
- # known prior to fetching an instance from the remote system.
- @@ -319,7 +316,7 @@ module ActiveResource
- raise ArgumentError, "Expected a hash" unless the_schema.kind_of? Hash
- the_schema.each do |k,v|
- - raise ArgumentError, "Unknown attribute type: #{v.inspect} for key: #{k.inspect}" unless v.nil? || KNOWN_ATTRIBUTE_TYPES.include?(v.to_sym)
- + raise ArgumentError, "Unknown attribute type: #{v.inspect} for key: #{k.inspect}" unless v.nil? || SchemaDefinition::KNOWN_ATTRIBUTE_TYPES.include?(v.to_sym)
- end
- @schema = the_schema.with_indifferent_access
- diff --git a/activeresource/lib/active_resource/schema_definition.rb b/activeresource/lib/active_resource/schema_definition.rb
- index 0f1cfd6..e53bb11 100644
- --- a/activeresource/lib/active_resource/schema_definition.rb
- +++ b/activeresource/lib/active_resource/schema_definition.rb
- @@ -3,6 +3,10 @@ require 'active_resource/exceptions'
- module ActiveResource # :nodoc:
- class SchemaDefinition # :nodoc:
- + # attributes can be known to be one of these types. They are easy to
- + # cast to/from.
- + KNOWN_ATTRIBUTE_TYPES = [:string, :integer, :float]
- +
- # An array of attribute definitions, representing the attributes that
- # have been defined.
- attr_accessor :attrs
- @@ -32,6 +36,5 @@ module ActiveResource # :nodoc:
- self
- end
- -
- end
- end
- diff --git a/activeresource/test/cases/base/schema_test.rb b/activeresource/test/cases/base/schema_test.rb
- index 6e659fb..b359a4a 100644
- --- a/activeresource/test/cases/base/schema_test.rb
- +++ b/activeresource/test/cases/base/schema_test.rb
- @@ -91,8 +91,8 @@ class SchemaTest < ActiveModel::TestCase
- end
- test "schema should accept all known attribute types as values" do
- - # I'd prefer to use ActiveResource::KNOWN_ATTRIBUTE_TYPES here...
- - [:string, :integer, :float].each do |the_type|
- + # I'd prefer to use here...
- + ActiveResource::SchemaDefinition::KNOWN_ATTRIBUTE_TYPES.each do |the_type|
- assert_nothing_raised("should have accepted #{the_type.inspect}"){ Person.schema = {'my_key' => the_type }}
- end
- end
- --
- 1.5.6.3
- From 9cbb6529d0a7054c54bac1c980f6d0dc53e68ebc Mon Sep 17 00:00:00 2001
- From: taryneast <rubygirl@taryneast.org>
- Date: Mon, 14 Dec 2009 19:59:37 +0000
- Subject: [PATCH] Test for all attr types and stringify them
- Firstly added a test that checks we can add all of the known attribute
- types.
- Secondly - stringified the set of known types - as this seems to be the
- running theme for Active Resource.
- ---
- activeresource/lib/active_resource/base.rb | 2 +-
- .../lib/active_resource/schema_definition.rb | 2 +-
- activeresource/test/cases/base/schema_test.rb | 28 ++++++++++++++-----
- 3 files changed, 22 insertions(+), 10 deletions(-)
- diff --git a/activeresource/lib/active_resource/base.rb b/activeresource/lib/active_resource/base.rb
- index c713889..85966ce 100644
- --- a/activeresource/lib/active_resource/base.rb
- +++ b/activeresource/lib/active_resource/base.rb
- @@ -316,7 +316,7 @@ module ActiveResource
- raise ArgumentError, "Expected a hash" unless the_schema.kind_of? Hash
- the_schema.each do |k,v|
- - raise ArgumentError, "Unknown attribute type: #{v.inspect} for key: #{k.inspect}" unless v.nil? || SchemaDefinition::KNOWN_ATTRIBUTE_TYPES.include?(v.to_sym)
- + raise ArgumentError, "Unknown attribute type: #{v.inspect} for key: #{k.inspect}" unless v.nil? || SchemaDefinition::KNOWN_ATTRIBUTE_TYPES.include?(v.to_s)
- end
- @schema = the_schema.with_indifferent_access
- diff --git a/activeresource/lib/active_resource/schema_definition.rb b/activeresource/lib/active_resource/schema_definition.rb
- index e53bb11..6358909 100644
- --- a/activeresource/lib/active_resource/schema_definition.rb
- +++ b/activeresource/lib/active_resource/schema_definition.rb
- @@ -5,7 +5,7 @@ module ActiveResource # :nodoc:
- # attributes can be known to be one of these types. They are easy to
- # cast to/from.
- - KNOWN_ATTRIBUTE_TYPES = [:string, :integer, :float]
- + KNOWN_ATTRIBUTE_TYPES = %w( string integer float )
- # An array of attribute definitions, representing the attributes that
- # have been defined.
- diff --git a/activeresource/test/cases/base/schema_test.rb b/activeresource/test/cases/base/schema_test.rb
- index b359a4a..5ce34d1 100644
- --- a/activeresource/test/cases/base/schema_test.rb
- +++ b/activeresource/test/cases/base/schema_test.rb
- @@ -192,7 +192,17 @@ class SchemaTest < ActiveModel::TestCase
- end
- end
- end
- -
- +
- + test "schema definition should store and return attribute set" do
- + assert_nothing_raised do
- + Person.define_schema do |s|
- + assert s.respond_to?(:attrs), "should return attributes in theory"
- + s.attribute :foo, :string
- + assert_equal({'foo' => 'string' }, s.attrs, "should return attributes in practice")
- + end
- + end
- + end
- +
- test "should be able to add attributes through define_schema" do
- assert_nothing_raised do
- Person.define_schema do |s|
- @@ -212,13 +222,15 @@ cla
Add Comment
Please, Sign In to add comment