app_attributes 0.5.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/.gitignore +4 -0
- data/Gemfile +4 -0
- data/README.md +45 -0
- data/Rakefile +2 -0
- data/app_attributes.gemspec +21 -0
- data/db/migrate/create_app_attributes.rb +17 -0
- data/lib/app_attributes/app_attribute.rb +15 -0
- data/lib/app_attributes/version.rb +3 -0
- data/lib/app_attributes.rb +47 -0
- data/test/app_attribute_test.rb +14 -0
- data/test/app_attributes_test.rb +17 -0
- data/test/test_helper.rb +0 -0
- metadata +66 -0
data/.gitignore
ADDED
data/Gemfile
ADDED
data/README.md
ADDED
@@ -0,0 +1,45 @@
|
|
1
|
+
# AppAttributes
|
2
|
+
|
3
|
+
A very simple polymorphic implementation of name-value pairs for any ActiveRecord model. The value is serialized to allow storage of ruby objects.
|
4
|
+
|
5
|
+
# Install
|
6
|
+
|
7
|
+
<pre>
|
8
|
+
sudo gem install app_attributes
|
9
|
+
</pre>
|
10
|
+
|
11
|
+
OR
|
12
|
+
|
13
|
+
<pre>
|
14
|
+
gem 'app_attributes'
|
15
|
+
bundle install
|
16
|
+
</pre>
|
17
|
+
|
18
|
+
# Usage
|
19
|
+
|
20
|
+
in your model:
|
21
|
+
|
22
|
+
<pre>
|
23
|
+
class Author < ActiveRecord::Base
|
24
|
+
include AppAttributes
|
25
|
+
|
26
|
+
ext_attribute :hat_size
|
27
|
+
# provides @author.hat_size, @author.hat_size=, @author.hat_size?
|
28
|
+
end
|
29
|
+
</pre>
|
30
|
+
|
31
|
+
# TODO
|
32
|
+
|
33
|
+
* automate migration. currently, you must manually copy/rename migration file in db/migrate
|
34
|
+
* finish tests
|
35
|
+
* specify dependencies
|
36
|
+
|
37
|
+
# Copyright and license
|
38
|
+
|
39
|
+
Copyright (c) 2011 Luke Wendling, released under the New BSD License
|
40
|
+
|
41
|
+
Contributors:
|
42
|
+
|
43
|
+
* Jeff Pihl
|
44
|
+
* Scott Robertson
|
45
|
+
* Mike Hansen
|
data/Rakefile
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
$:.push File.expand_path("../lib", __FILE__)
|
3
|
+
require "app_attributes/version"
|
4
|
+
|
5
|
+
Gem::Specification.new do |s|
|
6
|
+
s.name = "app_attributes"
|
7
|
+
s.version = AppAttributes::VERSION
|
8
|
+
s.platform = Gem::Platform::RUBY
|
9
|
+
s.authors = ["Luke Wendling"]
|
10
|
+
s.email = ["noreply@example.com"]
|
11
|
+
s.homepage = ""
|
12
|
+
s.summary = %q{Add simple name-value pairs to any ActiveRecord model}
|
13
|
+
s.description = %q{Add simple name-value pairs to any ActiveRecord model}
|
14
|
+
|
15
|
+
s.rubyforge_project = "app_attributes"
|
16
|
+
|
17
|
+
s.files = `git ls-files`.split("\n")
|
18
|
+
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
19
|
+
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
20
|
+
s.require_paths = ["lib"]
|
21
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
class CreateAppAttributes < ActiveRecord::Migration
|
2
|
+
def self.up
|
3
|
+
create_table :app_attributes do |t|
|
4
|
+
t.string :name
|
5
|
+
t.text :value
|
6
|
+
t.integer :attributable_id
|
7
|
+
t.string :attributable_type
|
8
|
+
t.timestamps
|
9
|
+
end
|
10
|
+
|
11
|
+
add_index :app_attributes, [:attributable_type, :attributable_id]
|
12
|
+
end
|
13
|
+
|
14
|
+
def self.down
|
15
|
+
drop_table :app_attributes
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
# polymorphic name-value pairs with serialized values
|
2
|
+
class AppAttribute < ActiveRecord::Base
|
3
|
+
# name :string
|
4
|
+
# value :text
|
5
|
+
# attributable_id :integer
|
6
|
+
# attributable_type :string
|
7
|
+
# timestamps
|
8
|
+
|
9
|
+
serialize :value
|
10
|
+
|
11
|
+
belongs_to :attributable, :polymorphic => true
|
12
|
+
|
13
|
+
validates_uniqueness_of :name, :scope => [:attributable_id, :attributable_type]
|
14
|
+
validates_presence_of :name
|
15
|
+
end
|
@@ -0,0 +1,47 @@
|
|
1
|
+
require File.join(File.dirname(__FILE__), 'app_attributes', 'app_attribute')
|
2
|
+
|
3
|
+
module AppAttributes
|
4
|
+
def self.included(base)
|
5
|
+
base.class_eval do
|
6
|
+
has_many :app_attributes, :as => :attributable, :dependent => :delete_all
|
7
|
+
end
|
8
|
+
base.extend(ClassMethods)
|
9
|
+
end
|
10
|
+
|
11
|
+
# Example:
|
12
|
+
# include AppAttributes
|
13
|
+
# ext_attribute :something_extra, 'none'
|
14
|
+
# ext_attribute :something_else
|
15
|
+
#
|
16
|
+
module ClassMethods
|
17
|
+
def ext_attribute(name, default_value=nil)
|
18
|
+
define_method("#{name}") do
|
19
|
+
if self.new_record?
|
20
|
+
app_attr = app_attributes.detect{|oa| oa.name == "#{name}"}
|
21
|
+
else
|
22
|
+
app_attr = app_attributes.find(:first, :conditions => {:name => "#{name}"})
|
23
|
+
end
|
24
|
+
(app_attr && app_attr.value) || default_value
|
25
|
+
end
|
26
|
+
|
27
|
+
define_method("#{name}?") do
|
28
|
+
! (value=send(name)).blank? && value != 'false'
|
29
|
+
end
|
30
|
+
|
31
|
+
define_method("#{name}=") do |raw_value|
|
32
|
+
new_value = raw_value == false ? 'false' : (raw_value.blank? ? default_value : raw_value)
|
33
|
+
if self.new_record?
|
34
|
+
return if new_value.blank? # fail silently if no default value and new value is blank
|
35
|
+
app_attr = app_attributes.detect{|oa| oa.name == "#{name}"}
|
36
|
+
app_attr ||= app_attributes.build(:name=>"#{name}")
|
37
|
+
app_attr.value = new_value
|
38
|
+
else
|
39
|
+
app_attr = app_attributes.find_or_create_by_name("#{name}")
|
40
|
+
# new_value = '-' if new_value.blank? # validation prevents blank value
|
41
|
+
app_attr.update_attributes(:value => new_value)
|
42
|
+
end
|
43
|
+
return app_attr.value
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
class AppAttributeTest < Test::Unit::TestCase
|
4
|
+
should validate_presence_of(:name)
|
5
|
+
|
6
|
+
should "validate uniqueness of name in scope" do
|
7
|
+
name = 'Boston'
|
8
|
+
assert_difference "AppAttribute.count" do
|
9
|
+
AppAttribute.create(:name => name, :attributable_id => 1, :attributable_type => 'Author')
|
10
|
+
end
|
11
|
+
app_attr = AppAttribute.new(:name => name, :attributable_id => 1, :attributable_type => 'Author')
|
12
|
+
assert app_attr.errors.on(:name)
|
13
|
+
end
|
14
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
class AppAttributesTest < Test::Unit::TestCase
|
4
|
+
|
5
|
+
context "when extending class attributes" do
|
6
|
+
setup do
|
7
|
+
AppAttribute.class_eval do
|
8
|
+
include AppAttributes
|
9
|
+
ext_attribute :test_attr
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
should "create dynamic getters and setters" do
|
14
|
+
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
data/test/test_helper.rb
ADDED
File without changes
|
metadata
ADDED
@@ -0,0 +1,66 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: app_attributes
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
prerelease:
|
5
|
+
version: 0.5.0
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Luke Wendling
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
|
13
|
+
date: 2011-04-20 00:00:00 Z
|
14
|
+
dependencies: []
|
15
|
+
|
16
|
+
description: Add simple name-value pairs to any ActiveRecord model
|
17
|
+
email:
|
18
|
+
- noreply@example.com
|
19
|
+
executables: []
|
20
|
+
|
21
|
+
extensions: []
|
22
|
+
|
23
|
+
extra_rdoc_files: []
|
24
|
+
|
25
|
+
files:
|
26
|
+
- .gitignore
|
27
|
+
- Gemfile
|
28
|
+
- README.md
|
29
|
+
- Rakefile
|
30
|
+
- app_attributes.gemspec
|
31
|
+
- db/migrate/create_app_attributes.rb
|
32
|
+
- lib/app_attributes.rb
|
33
|
+
- lib/app_attributes/app_attribute.rb
|
34
|
+
- lib/app_attributes/version.rb
|
35
|
+
- test/app_attribute_test.rb
|
36
|
+
- test/app_attributes_test.rb
|
37
|
+
- test/test_helper.rb
|
38
|
+
homepage: ""
|
39
|
+
licenses: []
|
40
|
+
|
41
|
+
post_install_message:
|
42
|
+
rdoc_options: []
|
43
|
+
|
44
|
+
require_paths:
|
45
|
+
- lib
|
46
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
47
|
+
none: false
|
48
|
+
requirements:
|
49
|
+
- - ">="
|
50
|
+
- !ruby/object:Gem::Version
|
51
|
+
version: "0"
|
52
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
53
|
+
none: false
|
54
|
+
requirements:
|
55
|
+
- - ">="
|
56
|
+
- !ruby/object:Gem::Version
|
57
|
+
version: "0"
|
58
|
+
requirements: []
|
59
|
+
|
60
|
+
rubyforge_project: app_attributes
|
61
|
+
rubygems_version: 1.7.2
|
62
|
+
signing_key:
|
63
|
+
specification_version: 3
|
64
|
+
summary: Add simple name-value pairs to any ActiveRecord model
|
65
|
+
test_files: []
|
66
|
+
|