serialize_with_coder 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,13 @@
1
+ module SerializeWithCoder
2
+
3
+ class CSVCoder
4
+ def load(data)
5
+ data.to_s.split(',')
6
+ end
7
+
8
+ def dump(obj)
9
+ obj.to_a.join(',')
10
+ end
11
+ end
12
+
13
+ end
@@ -0,0 +1,15 @@
1
+ require 'json'
2
+
3
+ module SerializeWithCoder
4
+
5
+ class JSONCoder
6
+ def load(data)
7
+ JSON.parse(data) rescue nil
8
+ end
9
+
10
+ def dump(obj)
11
+ obj.to_json rescue nil
12
+ end
13
+ end
14
+
15
+ end
@@ -0,0 +1,68 @@
1
+ module SerializeWithCoder
2
+
3
+ module ClassMethods
4
+
5
+ def serialize_with_coder(attr_name, class_name)
6
+ self.class_eval do
7
+ @@serialized_with_coder_fields ||= {}
8
+ @@serialized_with_coder_fields.merge!(
9
+ attr_name => class_name
10
+ )
11
+
12
+ before_save :synchronize_serialized_fields
13
+
14
+ define_method("reload_serialized_fields") do
15
+ @@serialized_with_coder_fields.each do |column, coder|
16
+ instance_variable_set("@#{column}", nil)
17
+ end
18
+ end
19
+
20
+ define_method("reload") do |*options|
21
+ reload_serialized_fields
22
+ super(options)
23
+ end
24
+ end
25
+
26
+ if column_names.include?(attr_name.to_s)
27
+ self.class_eval do
28
+ define_method("#{attr_name}=") do |val|
29
+ instance_variable_set("@#{attr_name}", val)
30
+ end
31
+
32
+ define_method(attr_name) do
33
+ instance_variable_get("@#{attr_name}") ?
34
+ instance_variable_get("@#{attr_name}") :
35
+ instance_variable_set("@#{attr_name}", class_name.load( read_attribute(attr_name) ))
36
+ end
37
+
38
+ define_method("#{attr_name}_changed?") do
39
+ class_name.load( read_attribute(attr_name) ) != send(attr_name)
40
+ end
41
+ end
42
+ else
43
+ raise "There is no column named #{attr_name}!"
44
+ end
45
+
46
+ define_method("attribute_for_inspect") do |attr_name|
47
+ value = @@serialized_with_coder_fields[attr_name.to_sym] ?
48
+ send(attr_name) :
49
+ read_attribute(attr_name)
50
+
51
+ if value.is_a?(String) && value.length > 50
52
+ "#{value[0..50]}...".inspect
53
+ elsif value.is_a?(Date) || value.is_a?(Time)
54
+ %("#{value.to_s(:db)}")
55
+ else
56
+ value.inspect
57
+ end
58
+ end
59
+
60
+ define_method("synchronize_serialized_fields") do
61
+ @@serialized_with_coder_fields.each do |column, coder|
62
+ write_attribute(column, coder.dump( instance_variable_get("@#{column}") )) if send("#{column}_changed?")
63
+ end
64
+ end
65
+
66
+ end
67
+ end
68
+ end
@@ -0,0 +1,101 @@
1
+ require 'test_helper'
2
+
3
+ class User < ActiveRecord::Base
4
+
5
+ serialize_with_coder :newsletters, SerializeWithCoder::CSVCoder.new
6
+ serialize_with_coder :notes, SerializeWithCoder::JSONCoder.new
7
+
8
+ def inspect
9
+ attributes_as_nice_string = self.class.column_names.collect { |name|
10
+ if has_attribute?(name)
11
+ "#{name}: #{attribute_for_inspect(name)}"
12
+ end
13
+ }.compact.join(", ")
14
+ "#<#{self.class} #{attributes_as_nice_string}>"
15
+ end
16
+
17
+ end
18
+
19
+ class SerializeWithCoderTest < Test::Unit::TestCase
20
+
21
+ def setup
22
+ @user = User.create(:name => "Dhalsim")
23
+ end
24
+
25
+ def setup_notes
26
+ @note = {
27
+ 'title' => 'First',
28
+ 'body' => 'Perfect body'
29
+ }
30
+
31
+ @note2 = {
32
+ 'title' => 'Second',
33
+ 'body' => 'Score!'
34
+ }
35
+ end
36
+
37
+ # Serialize with CSV coder
38
+
39
+ def test_serialize_to_csv
40
+ @user.newsletters = ["FREE", "PREMIUM"]
41
+ @user.save
42
+
43
+ assert_equal "FREE,PREMIUM", @user.read_attribute(:newsletters)
44
+ end
45
+
46
+ def test_deserialized_from_csv
47
+ @user.newsletters = ["FREE", "PREMIUM"]
48
+ @user.save
49
+
50
+ user = User.find(@user.id)
51
+
52
+ assert_equal ["FREE", "PREMIUM"], user.newsletters
53
+ end
54
+
55
+ # Serialize with JSON coder
56
+
57
+ def test_serialize_to_json
58
+ setup_notes
59
+
60
+ @user.notes = [@note, @note2]
61
+ @user.save
62
+
63
+ assert_match /\[.+\]/, @user.read_attribute(:notes)
64
+
65
+ assert_match /\"title\":\"First\"/, @user.read_attribute(:notes)
66
+ assert_match /\"body\":\"Perfect body\"/, @user.read_attribute(:notes)
67
+ assert_match /\"title\":\"Second\"/, @user.read_attribute(:notes)
68
+ assert_match /\"body\":\"Score!\"/, @user.read_attribute(:notes)
69
+ end
70
+
71
+ def test_deserialized_from_json
72
+ setup_notes
73
+
74
+ @user.notes = [@note, @note2]
75
+ @user.save
76
+
77
+ user = User.find(@user.id)
78
+
79
+ assert user.notes.include?(@note)
80
+ assert user.notes.include?(@note2)
81
+ end
82
+
83
+ # Serialize with both coders
84
+
85
+ def test_serialize_with_both_coders
86
+ setup_notes
87
+
88
+ @user.newsletters = ["FREE", "PREMIUM"]
89
+ @user.notes = [@note, @note2]
90
+
91
+ @user.save
92
+
93
+ user = User.find(@user.id)
94
+
95
+ assert_equal ["FREE", "PREMIUM"], user.newsletters
96
+
97
+ assert user.notes.include?(@note)
98
+ assert user.notes.include?(@note2)
99
+ end
100
+
101
+ end
@@ -0,0 +1,24 @@
1
+ $:.unshift(File.dirname(__FILE__) + '/..')
2
+ $:.unshift(File.dirname(__FILE__) + '/../lib')
3
+
4
+ require 'rubygems'
5
+ require 'active_record'
6
+ require 'test/unit'
7
+
8
+ require 'serialize_with_coder'
9
+ require 'coders/csv_coder'
10
+ require 'coders/json_coder'
11
+
12
+ require 'init'
13
+
14
+ ActiveRecord::Base.establish_connection(:adapter => 'sqlite3', :database => ':memory:')
15
+
16
+ [:users].each do |table|
17
+ ActiveRecord::Base.connection.drop_table table rescue nil
18
+ end
19
+
20
+ ActiveRecord::Base.connection.create_table :users do |t|
21
+ t.string :name
22
+ t.text :newsletters
23
+ t.text :notes
24
+ end
metadata ADDED
@@ -0,0 +1,113 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: serialize_with_coder
3
+ version: !ruby/object:Gem::Version
4
+ hash: 27
5
+ prerelease:
6
+ segments:
7
+ - 0
8
+ - 1
9
+ - 0
10
+ version: 0.1.0
11
+ platform: ruby
12
+ authors:
13
+ - Maciej Gajek
14
+ autorequire:
15
+ bindir: bin
16
+ cert_chain: []
17
+
18
+ date: 2011-11-12 00:00:00 +01:00
19
+ default_executable:
20
+ dependencies:
21
+ - !ruby/object:Gem::Dependency
22
+ name: activerecord
23
+ prerelease: false
24
+ requirement: &id001 !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ~>
28
+ - !ruby/object:Gem::Version
29
+ hash: 7
30
+ segments:
31
+ - 2
32
+ version: "2"
33
+ type: :runtime
34
+ version_requirements: *id001
35
+ - !ruby/object:Gem::Dependency
36
+ name: json
37
+ prerelease: false
38
+ requirement: &id002 !ruby/object:Gem::Requirement
39
+ none: false
40
+ requirements:
41
+ - - ">="
42
+ - !ruby/object:Gem::Version
43
+ hash: 3
44
+ segments:
45
+ - 0
46
+ version: "0"
47
+ type: :runtime
48
+ version_requirements: *id002
49
+ - !ruby/object:Gem::Dependency
50
+ name: sqlite3
51
+ prerelease: false
52
+ requirement: &id003 !ruby/object:Gem::Requirement
53
+ none: false
54
+ requirements:
55
+ - - ">="
56
+ - !ruby/object:Gem::Version
57
+ hash: 3
58
+ segments:
59
+ - 0
60
+ version: "0"
61
+ type: :development
62
+ version_requirements: *id003
63
+ description: serialize_with_coder is an ActiveRecord extended serialize function which acts like Rails 3.1 one - you can use custom coder as storing engine. Including 2 sample coders - CSV and JSON.
64
+ email: maltize@gmail.com
65
+ executables: []
66
+
67
+ extensions: []
68
+
69
+ extra_rdoc_files: []
70
+
71
+ files:
72
+ - lib/coders/csv_coder.rb
73
+ - lib/coders/json_coder.rb
74
+ - lib/serialize_with_coder.rb
75
+ - test/serialize_with_coder_test.rb
76
+ - test/test_helper.rb
77
+ has_rdoc: true
78
+ homepage: https://github.com/maltize/serialize_with_coder
79
+ licenses: []
80
+
81
+ post_install_message:
82
+ rdoc_options: []
83
+
84
+ require_paths:
85
+ - lib
86
+ required_ruby_version: !ruby/object:Gem::Requirement
87
+ none: false
88
+ requirements:
89
+ - - ">="
90
+ - !ruby/object:Gem::Version
91
+ hash: 3
92
+ segments:
93
+ - 0
94
+ version: "0"
95
+ required_rubygems_version: !ruby/object:Gem::Requirement
96
+ none: false
97
+ requirements:
98
+ - - ">="
99
+ - !ruby/object:Gem::Version
100
+ hash: 3
101
+ segments:
102
+ - 0
103
+ version: "0"
104
+ requirements: []
105
+
106
+ rubyforge_project:
107
+ rubygems_version: 1.5.0
108
+ signing_key:
109
+ specification_version: 3
110
+ summary: Serialize with Coder
111
+ test_files:
112
+ - test/serialize_with_coder_test.rb
113
+ - test/test_helper.rb