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.
- data/lib/coders/csv_coder.rb +13 -0
- data/lib/coders/json_coder.rb +15 -0
- data/lib/serialize_with_coder.rb +68 -0
- data/test/serialize_with_coder_test.rb +101 -0
- data/test/test_helper.rb +24 -0
- metadata +113 -0
@@ -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
|
data/test/test_helper.rb
ADDED
@@ -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
|