ref: refs/heads/jr-basemodel
commit 8cd9e52f2b69b325acdadff7cd8fc77d29c346c1
Author: Josef Reidinger
Date: Mon Dec 14 09:29:08 2009 +0100
improve base model documentation
fix attr_serialized and add its test to test-suite
---
webservice/lib/base_model/base.rb | 12 +++++--
webservice/lib/base_model/serialization.rb | 26 ++++++++++++++--
.../lib/base_model/serializers/json_serializer.rb | 4 ++
.../lib/base_model/serializers/xml_serializer.rb | 10 +++++-
webservice/test/unit/base_model_test.rb | 32 ++++++++++++++++++-
5 files changed, 74 insertions(+), 10 deletions(-)
diff --git a/webservice/lib/base_model/base.rb b/webservice/lib/base_model/base.rb
index aec330f..3374982 100644
--- a/webservice/lib/base_model/base.rb
+++ b/webservice/lib/base_model/base.rb
@@ -110,21 +110,27 @@ module BaseModel
true
end
-#remove overwritten method_missing from activeRecord
+#remove overwritten method_missing from activeRecord (as Base model doesn't know attributes)
alias :method_missing_orig :method_missing
+ #required by validations
include ActiveRecord::AttributeMethods
alias :method_missing :method_missing_orig
-#remove overwritten respond_to
+#remove overwritten respond_to (as Base model doesn't have attributes
alias :respond_to? :respond_to_without_attributes?
+ #Validations in model
include ActiveRecord::Validations
+ #Callbacks in model
include ActiveRecord::Callbacks
+ #Mass assignment support
include BaseModel::MassAssignment
+ #serialization of models
include BaseModel::Serialization
- include YastRoles #to access permission check in models
+ #permission check in models
+ include YastRoles
end
end
diff --git a/webservice/lib/base_model/serialization.rb b/webservice/lib/base_model/serialization.rb
index f822afa..0777301 100644
--- a/webservice/lib/base_model/serialization.rb
+++ b/webservice/lib/base_model/serialization.rb
@@ -1,12 +1,22 @@
module BaseModel
module Serialization
+ # Helper class for serializer implementation.
+ #
+ # Inspired by ActiveRecord Serializer
class Serializer
- attr_reader :options, :attributes
+ #passed options to serializer
+ attr_reader :options
+ #attributes to serialize
+ attr_reader :attributes
+ # initialize serializer
+ #
+ # model:: model to serialize
+ # options:: generic options for serializer, not used now
def initialize(model,options={})
@model = model
@options = options
- @attributes = options[:attributes]
+ @attributes = model.class.serialized_attributes
unless @attributes
@attributes = model.instance_variables.collect { |v| v.to_sym }
end
@@ -18,11 +28,21 @@ module BaseModel
end
module ClassMethods
+ # defines attributes which should be serialized
+ # usage (class with two attributes to serialize):
+ # class Test
+ # include Serialization
+ # attr_serialized :arg1
+ # attr_serialized :arg2
+ # end
def attr_serialized(*args)
@attr_serialized ||= []
- @attr_serialized.concat args
+ @attr_serialized.concat args.collect { |v| "@#{v.to_s}".to_sym }
end
+ # Gets attributes which should be serialized, containing @ at beggining
+ # so result from attr_serialized example is:
+ # [ :'@arg1', :'arg2' ]
def serialized_attributes
@attr_serialized
end
diff --git a/webservice/lib/base_model/serializers/json_serializer.rb b/webservice/lib/base_model/serializers/json_serializer.rb
index f67e0bb..ad984f0 100644
--- a/webservice/lib/base_model/serializers/json_serializer.rb
+++ b/webservice/lib/base_model/serializers/json_serializer.rb
@@ -1,15 +1,19 @@
require 'active_support/json'
module BaseModel
module Serialization
+ # serializes model to json
+ # as root element uses singular model name
def to_json(options={},&block)
super
end
+ # restore model from json
def from_json(json)
hash = ActiveSupport::JSON.decode(json)
load(hash.values.first)
end
+private
def as_json(options={})
hash = {}
Serializer.new(self,options).attributes.each do |attr|
diff --git a/webservice/lib/base_model/serializers/xml_serializer.rb b/webservice/lib/base_model/serializers/xml_serializer.rb
index de98e56..e8289a6 100644
--- a/webservice/lib/base_model/serializers/xml_serializer.rb
+++ b/webservice/lib/base_model/serializers/xml_serializer.rb
@@ -1,11 +1,16 @@
module BaseModel
module Serialization
+ # Serializes model to XML
+ #
+ # +WARNING+:: keys from hash is get to tags unescaped, so don't use hash with keys which can break XML tag (this behavior might change in future)
+ # options:: recognizes common Builder::XmlMarkup options (if root is not given, it uses singular of model name )
+ # block:: not used now
def to_xml(options={},&block)
- options[:attributes] = self.class.serialized_attributes
serializer = XmlSerializer.new(self,options)
block_given? ? serializer.serialize(&block) : serializer.serialize
end
+ # loads model from xml
def from_xml(xml)
load(Hash.from_xml(xml).values.first)
self
@@ -25,7 +30,7 @@ module BaseModel
end
protected
-#place for all types for special serializing
+ #place for all types for special serializing
def serialize_value(name,value,builder)
if value.is_a? Array
builder.tag!(name,{:type => "array"}) do
@@ -43,6 +48,7 @@ module BaseModel
type = XML_TYPE_NAMES[value.class.to_s]
opts = {}
opts[:type] = type if type
+ #NOTE: can be optimalized for primitive types like boolean or numbers to avoid XML escaping
builder.tag!(name,value.to_s,opts)
end
end
diff --git a/webservice/test/unit/base_model_test.rb b/webservice/test/unit/base_model_test.rb
index 7a2fffd..f86985c 100644
--- a/webservice/test/unit/base_model_test.rb
+++ b/webservice/test/unit/base_model_test.rb
@@ -16,11 +16,20 @@ class BaseModelTest < ActiveSupport::TestCase
attr_accessor :arg1, :arg2
attr_accessible :arg1
+ attr_serialized :arg1
def call
@callback_used = true;
end
end
+ class Test3 < BaseModel::Base
+
+ attr_accessor :arg1, :arg2
+ attr_serialized :arg1
+ def call
+ @callback_used = true;
+ end
+ end
def test_validations
test = Test.new
@@ -68,7 +77,6 @@ COMPLEX_DATA = {
test.carg = COMPLEX_DATA
xml = test.to_xml
assert xml
- puts xml.inspect
test2 = Test.new
test2.from_xml xml
assert_equal "last", test2.arg1
@@ -80,7 +88,6 @@ COMPLEX_DATA = {
test= Test.new(MASS_DATA)
test.carg = COMPLEX_DATA
json = test.to_json
- puts json.inspect
assert json
test2 = Test.new
test2.from_json json
@@ -88,4 +95,25 @@ COMPLEX_DATA = {
assert_equal "5", test2.arg2
assert_equal COMPLEX_DATA, test2.carg
end
+
+ def test_attr_serializable
+ test = Test3.new
+ test.arg1 = "dev"
+ test.arg2 = "null"
+ xml = test.to_xml
+ assert xml
+ test2 = Test3.new
+ test2.from_xml xml
+ assert_equal "dev",test2.arg1
+ assert_nil test2.arg2
+ test = Test3.new
+ test.arg1 = "dev"
+ test.arg2 = "null"
+ json = test.to_json
+ assert json
+ test2 = Test3.new
+ test2.from_json json
+ assert_equal "dev",test2.arg1
+ assert_nil test2.arg2
+ end
end
--
To unsubscribe, e-mail: yast-commit+unsubscribe@opensuse.org
For additional commands, e-mail: yast-commit+help@opensuse.org