ar_serialized_array 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -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