ar_serialized_array 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,40 @@
1
+ Serialize an array in one column.
2
+
3
+ - [] when not set
4
+ - `xxx_as_text` / `xxx_as_text=` accessors to edit in forms
5
+ - `:on_set` callback for cleanup
6
+ - stores NULL when given array was empty (all empty -> `IS NULL`)
7
+
8
+ Install
9
+ =======
10
+ - As Rails plugin: `script/plugin install git://github.com/grosser/ar_serialized_array.git `
11
+ - As gem: ` sudo gem install ar_serialized_array -s http://gemcutter.org `
12
+
13
+
14
+ Usage
15
+ =====
16
+
17
+ class User < ActiveRecord::Base
18
+ serialized_array :product_ids, :accessor => :product_ids_as_text, :on_set=>lambda{|x| x.map(&:to_i).uniq }
19
+ end
20
+
21
+ User.new.product_ids # []
22
+
23
+ user.product_ids_as_text = "1, , 12323 , 23, 1"
24
+ user.product_ids # [1, 12323, 23]
25
+ user.product_ids_as_text # "1, 12323, 23"
26
+
27
+ f.text_area :product_ids_as_text
28
+
29
+ filled = User.all(:conditions => {:product_ids=>[1,3].to_yaml})
30
+ empty = User.all(:conditions => {:product_ids=>nil})
31
+
32
+ TODO
33
+ ====
34
+ - add support for `user.product_ids << 1`
35
+
36
+ Author
37
+ ======
38
+ [Michael Grosser](http://pragmatig.wordpress.com)
39
+ grosser.michael@gmail.com
40
+ Hereby placed under public domain, do what you want, just do not hold me accountable...
@@ -0,0 +1,23 @@
1
+ desc "Run all specs in spec directory"
2
+ task :default do
3
+ options = "--colour --format progress --loadby --reverse"
4
+ files = FileList['spec/**/*_spec.rb']
5
+ system("spec #{options} #{files}")
6
+ end
7
+
8
+ begin
9
+ require 'jeweler'
10
+ project_name = 'ar_serialized_array'
11
+ Jeweler::Tasks.new do |gem|
12
+ gem.name = project_name
13
+ gem.summary = "Serialize an array in a column, [] when no set, xx_as_text accessors and more."
14
+ gem.email = "grosser.michael@gmail.com"
15
+ gem.homepage = "http://github.com/grosser/#{project_name}"
16
+ gem.authors = ["Michael Grosser"]
17
+ gem.add_dependency ['activerecord']
18
+ end
19
+
20
+ Jeweler::GemcutterTasks.new
21
+ rescue LoadError
22
+ puts "Jeweler, or one of its dependencies, is not available. Install it with: sudo gem install technicalpickles-jeweler -s http://gems.github.com"
23
+ end
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 0.1.0
@@ -0,0 +1,52 @@
1
+ # Generated by jeweler
2
+ # DO NOT EDIT THIS FILE DIRECTLY
3
+ # Instead, edit Jeweler::Tasks in Rakefile, and run the gemspec command
4
+ # -*- encoding: utf-8 -*-
5
+
6
+ Gem::Specification.new do |s|
7
+ s.name = %q{ar_serialized_array}
8
+ s.version = "0.1.0"
9
+
10
+ s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
+ s.authors = ["Michael Grosser"]
12
+ s.date = %q{2009-11-16}
13
+ s.email = %q{grosser.michael@gmail.com}
14
+ s.extra_rdoc_files = [
15
+ "README.markdown"
16
+ ]
17
+ s.files = [
18
+ "README.markdown",
19
+ "Rakefile",
20
+ "VERSION",
21
+ "ar_serialized_array.gemspec",
22
+ "init.rb",
23
+ "lib/ar_serialized_array.rb",
24
+ "spec/ar_serialized_array_spec.rb",
25
+ "spec/setup_test_model.rb",
26
+ "spec/spec_helper.rb"
27
+ ]
28
+ s.homepage = %q{http://github.com/grosser/ar_serialized_array}
29
+ s.rdoc_options = ["--charset=UTF-8"]
30
+ s.require_paths = ["lib"]
31
+ s.rubygems_version = %q{1.3.5}
32
+ s.summary = %q{Serialize an array in a column, [] when no set, xx_as_text accessors and more.}
33
+ s.test_files = [
34
+ "spec/spec_helper.rb",
35
+ "spec/setup_test_model.rb",
36
+ "spec/ar_serialized_array_spec.rb"
37
+ ]
38
+
39
+ if s.respond_to? :specification_version then
40
+ current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
41
+ s.specification_version = 3
42
+
43
+ if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
44
+ s.add_runtime_dependency(%q<activerecord>, [">= 0"])
45
+ else
46
+ s.add_dependency(%q<activerecord>, [">= 0"])
47
+ end
48
+ else
49
+ s.add_dependency(%q<activerecord>, [">= 0"])
50
+ end
51
+ end
52
+
data/init.rb ADDED
@@ -0,0 +1 @@
1
+ require 'ar_serialized_array'
@@ -0,0 +1,37 @@
1
+ require 'activerecord'
2
+
3
+ module ARSerializedArray
4
+ VERSION = File.read( File.join(File.dirname(__FILE__),'..','VERSION') ).strip
5
+
6
+ def serialized_array(attr_name, options={})
7
+ options[:on_set] ||= lambda{|x|x}
8
+
9
+ # getter
10
+ define_method attr_name do
11
+ YAML.load(read_attribute(attr_name).to_s) || []
12
+ end
13
+
14
+ # setter
15
+ define_method "#{attr_name}=" do |value|
16
+ value = options[:on_set].call(value) || []
17
+ raise "Expected an Array, got: #{value.inspect}" unless value.is_a? Array
18
+ value = (value.empty? ? nil : value.to_yaml)
19
+ write_attribute attr_name, value
20
+ end
21
+
22
+ # accessors e.g. xxx_as_text
23
+ if options[:accessor]
24
+ #getter
25
+ define_method options[:accessor] do
26
+ send(attr_name) * ", "
27
+ end
28
+
29
+ #setter
30
+ define_method "#{options[:accessor]}=" do |value|
31
+ send "#{attr_name}=", value.to_s.split(',').reject(&:blank?).map(&:strip)
32
+ end
33
+ end
34
+ end
35
+ end
36
+
37
+ ActiveRecord::Base.send(:extend, ARSerializedArray)
@@ -0,0 +1,79 @@
1
+ require "spec/spec_helper"
2
+
3
+ describe 'ar_serialized_array' do
4
+ describe 'basics' do
5
+ it "is an empty array by default" do
6
+ UserPlain.new.product_ids.should == []
7
+ end
8
+
9
+ it "serializes on set" do
10
+ user = UserPlain.create!(:product_ids => [1, 2])
11
+ UserPlain.find(user.id).product_ids.should == [1, 2]
12
+ end
13
+
14
+ it "can save an empty array" do
15
+ user = UserPlain.create!(:product_ids => [])
16
+ UserPlain.find(user.id).product_ids.should == []
17
+ end
18
+
19
+ it "can save nil" do
20
+ user = UserPlain.create!(:product_ids => nil)
21
+ UserPlain.find(user.id).product_ids.should == []
22
+ end
23
+
24
+ it "stores empty arrays as NULL" do
25
+ user = UserPlain.create!(:product_ids => [])
26
+ UserPlain.first(:conditions => {:id => user.id, :product_ids => nil}).should == user
27
+ end
28
+
29
+ it "can search by array" do
30
+ user = UserPlain.create!(:product_ids => [1])
31
+ UserPlain.first(:conditions => {:id => user.id, :product_ids => [1].to_yaml}).should == user
32
+ end
33
+
34
+ it "raises when non-array is given" do
35
+ lambda{ UserPlain.create!(:product_ids => '') }.should raise_error
36
+ end
37
+ end
38
+
39
+ describe 'with accessor' do
40
+ it "can access the array as text" do
41
+ UserWithAccessor.new(:product_ids => [1,2,3]).product_ids_as_text.should == '1, 2, 3'
42
+ end
43
+
44
+ it "can set arrays via text" do
45
+ UserWithAccessor.new(:product_ids_as_text => '1, 2, 3').product_ids.should == ['1','2','3']
46
+ end
47
+
48
+ it "is symetric" do
49
+ text = '1, 2, 3'
50
+ UserWithAccessor.new(:product_ids_as_text => text).product_ids_as_text.should == text
51
+ end
52
+
53
+ it "accepts nil as empty" do
54
+ UserWithAccessor.new(:product_ids_as_text => nil).product_ids.should == []
55
+ end
56
+
57
+ it "is blank when unset" do
58
+ UserWithAccessor.new.product_ids_as_text.should == ''
59
+ end
60
+
61
+ it "is blank when empty" do
62
+ UserWithAccessor.new(:product_ids => []).product_ids_as_text.should == ''
63
+ end
64
+ end
65
+
66
+ describe 'with on_set' do
67
+ it "is used when storing normally" do
68
+ User.new(:product_ids => ['1','2','2']).product_ids.should == [1,2]
69
+ end
70
+
71
+ it "is used when storing through accessor" do
72
+ User.new(:product_ids_as_text => '1,2,2').product_ids.should == [1,2]
73
+ end
74
+ end
75
+
76
+ it "has a VERSION" do
77
+ ARSerializedArray::VERSION.should =~ /^\d+\.\d+\.\d+$/
78
+ end
79
+ end
@@ -0,0 +1,30 @@
1
+ # connect
2
+ ActiveRecord::Base.configurations = {"test" => {
3
+ :adapter => "sqlite3",
4
+ :database => ":memory:",
5
+ }.with_indifferent_access}
6
+
7
+ ActiveRecord::Base.establish_connection(:test)
8
+
9
+ # create tables
10
+ ActiveRecord::Schema.define(:version => 1) do
11
+ create_table :users do |t|
12
+ t.string :product_ids
13
+ end
14
+ end
15
+
16
+ # create models
17
+ class User < ActiveRecord::Base
18
+ serialized_array :product_ids, :accessor => :product_ids_as_text, :on_set=>lambda{|x| x.map(&:to_i).uniq}
19
+ end
20
+
21
+ class UserWithAccessor < ActiveRecord::Base
22
+ self.table_name = 'users'
23
+ serialized_array :product_ids, :accessor => :product_ids_as_text
24
+ end
25
+
26
+
27
+ class UserPlain < ActiveRecord::Base
28
+ self.table_name = 'users'
29
+ serialized_array :product_ids
30
+ end
@@ -0,0 +1,3 @@
1
+ $LOAD_PATH << "lib"
2
+ require "init"
3
+ require "spec/setup_test_model"
metadata ADDED
@@ -0,0 +1,74 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: ar_serialized_array
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Michael Grosser
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+
12
+ date: 2009-11-16 00:00:00 +01:00
13
+ default_executable:
14
+ dependencies:
15
+ - !ruby/object:Gem::Dependency
16
+ name: activerecord
17
+ type: :runtime
18
+ version_requirement:
19
+ version_requirements: !ruby/object:Gem::Requirement
20
+ requirements:
21
+ - - ">="
22
+ - !ruby/object:Gem::Version
23
+ version: "0"
24
+ version:
25
+ description:
26
+ email: grosser.michael@gmail.com
27
+ executables: []
28
+
29
+ extensions: []
30
+
31
+ extra_rdoc_files:
32
+ - README.markdown
33
+ files:
34
+ - README.markdown
35
+ - Rakefile
36
+ - VERSION
37
+ - ar_serialized_array.gemspec
38
+ - init.rb
39
+ - lib/ar_serialized_array.rb
40
+ - spec/ar_serialized_array_spec.rb
41
+ - spec/setup_test_model.rb
42
+ - spec/spec_helper.rb
43
+ has_rdoc: true
44
+ homepage: http://github.com/grosser/ar_serialized_array
45
+ licenses: []
46
+
47
+ post_install_message:
48
+ rdoc_options:
49
+ - --charset=UTF-8
50
+ require_paths:
51
+ - lib
52
+ required_ruby_version: !ruby/object:Gem::Requirement
53
+ requirements:
54
+ - - ">="
55
+ - !ruby/object:Gem::Version
56
+ version: "0"
57
+ version:
58
+ required_rubygems_version: !ruby/object:Gem::Requirement
59
+ requirements:
60
+ - - ">="
61
+ - !ruby/object:Gem::Version
62
+ version: "0"
63
+ version:
64
+ requirements: []
65
+
66
+ rubyforge_project:
67
+ rubygems_version: 1.3.5
68
+ signing_key:
69
+ specification_version: 3
70
+ summary: Serialize an array in a column, [] when no set, xx_as_text accessors and more.
71
+ test_files:
72
+ - spec/spec_helper.rb
73
+ - spec/setup_test_model.rb
74
+ - spec/ar_serialized_array_spec.rb