banyan 1.0.1
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.
- checksums.yaml +15 -0
- data/.gitignore +1 -0
- data/Gemfile +3 -0
- data/MIT-LICENSE +20 -0
- data/README.md +102 -0
- data/Rakefile +12 -0
- data/banyan.gemspec +25 -0
- data/lib/banyan/categorizable.rb +42 -0
- data/lib/banyan/categorization.rb +9 -0
- data/lib/banyan/category.rb +23 -0
- data/lib/banyan/category_group.rb +23 -0
- data/lib/banyan/version.rb +3 -0
- data/lib/banyan.rb +13 -0
- data/lib/generators/banyan/banyan_generator.rb +20 -0
- data/lib/generators/banyan/templates/migration.rb +54 -0
- data/spec/banyan/banyan_category_group_spec.rb +62 -0
- data/spec/banyan/banyan_category_spec.rb +62 -0
- data/spec/banyan/banyan_group_model_spec.rb +25 -0
- data/spec/banyan/banyan_model_spec.rb +30 -0
- data/spec/banyan/banyan_single_group_model_spec.rb +18 -0
- data/spec/factories/banyan_category.rb +5 -0
- data/spec/factories/banyan_category_group.rb +5 -0
- data/spec/factories/banyan_group_model.rb +4 -0
- data/spec/factories/banyan_model.rb +5 -0
- data/spec/factories/banyan_single_group_model.rb +4 -0
- data/spec/spec_helper.rb +37 -0
- data/spec/support/00_schema.rb +49 -0
- data/spec/support/banyan_group_model.rb +5 -0
- data/spec/support/banyan_model.rb +5 -0
- data/spec/support/banyan_single_group_model.rb +3 -0
- metadata +187 -0
checksums.yaml
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
---
|
2
|
+
!binary "U0hBMQ==":
|
3
|
+
metadata.gz: !binary |-
|
4
|
+
NGYxYzEyOGNkYmZhN2MzZjJlZGFlMmYxMmY0M2ZiODBhYWRjNmYyYQ==
|
5
|
+
data.tar.gz: !binary |-
|
6
|
+
OTg5ZTE3MzRlOTg4YWUzNTJkZWNhMGMzMWI4N2Q2NWZhOThlMjdjOQ==
|
7
|
+
!binary "U0hBNTEy":
|
8
|
+
metadata.gz: !binary |-
|
9
|
+
NjBjNzVjOTQyMWZkMTJkNjZkYmVhZmE5N2M0ZWU4NjJlZGE3MDk3NjRlMmZk
|
10
|
+
ZWExZDRjNjVmMjAxYjIwYjEwYTBkOTdlNWM3YmNhNmUwMTM3YTBhOGQzZmE1
|
11
|
+
MDJlMmRhNmQ2Y2IzMzA2YTYwYmFhNWVhNjc0YWE3M2EyOTVjZWM=
|
12
|
+
data.tar.gz: !binary |-
|
13
|
+
MjM3OTNmODAyNTEzYzRlZDU1YTZiOGM3YjE3YzFmODJhZjA2ZDg4OGFkYjZi
|
14
|
+
NGI0MmYxZGY1Y2U1ZGJlNGYyNmJjZTZkMjhhMjVkOGQ3M2E0ZDY1Y2U1N2Fl
|
15
|
+
MmM1NzUyM2FkNDJhMmVlNjk5ZDM0NWQ1OWNlMjg2NWU2YjZhNzQ=
|
data/.gitignore
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
Gemfile.lock
|
data/Gemfile
ADDED
data/MIT-LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright (c) 2011-2012 Partnerpedia Solutions Inc.
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,102 @@
|
|
1
|
+
# Banyan
|
2
|
+
|
3
|
+
## Installation
|
4
|
+
|
5
|
+
In Gemfile
|
6
|
+
|
7
|
+
``` ruby
|
8
|
+
gem 'banyan', :git => 'git://github.com/partnerpedia/banyan.git'
|
9
|
+
```
|
10
|
+
|
11
|
+
Then:
|
12
|
+
|
13
|
+
``` bash
|
14
|
+
$ bundle install
|
15
|
+
$ rails generate banyan
|
16
|
+
$ rake db:migrate
|
17
|
+
```
|
18
|
+
|
19
|
+
This will install Banyan and create required database migration.
|
20
|
+
|
21
|
+
## Usage of Categories
|
22
|
+
|
23
|
+
Each ActiveRecord can have assigned categories. In order to do that you can add this line to model:
|
24
|
+
|
25
|
+
``` ruby
|
26
|
+
class MyModel < ActiveRecord::Base
|
27
|
+
acts_as_categorizable
|
28
|
+
end
|
29
|
+
```
|
30
|
+
|
31
|
+
This will create "categories" association, which will be able to assign multiple Banyan::Category objects.
|
32
|
+
|
33
|
+
``` ruby
|
34
|
+
my_model = MyModel.new
|
35
|
+
my_model.categories # => []
|
36
|
+
my_model.categories << Banyan::Category.first
|
37
|
+
```
|
38
|
+
|
39
|
+
You can also specify that you want only one Category per model instance:
|
40
|
+
|
41
|
+
``` ruby
|
42
|
+
class MyModel < ActiveRecord::Base
|
43
|
+
acts_as_categorizable :single => true
|
44
|
+
end
|
45
|
+
```
|
46
|
+
|
47
|
+
In that case "category" association will be created:
|
48
|
+
|
49
|
+
``` ruby
|
50
|
+
my_model = MyModel.new
|
51
|
+
my_model.category # => nil
|
52
|
+
my_model.category = Banyan::Category.first
|
53
|
+
```
|
54
|
+
|
55
|
+
Each Banyan::Category object can have following attributes:
|
56
|
+
|
57
|
+
- [string] tag: this field is indexed and is each to search by for specific Category
|
58
|
+
- [string] name: this is translated(via Globalize3) field, used to describe Category for end user
|
59
|
+
- [collection] categories: each Category can have children
|
60
|
+
- [collection] category_groups: each Category can have multiple CategoryGroups(described later). This is many-to-many association
|
61
|
+
|
62
|
+
If you want to access your model list for specified category then special association is created using your model name and "_categorizations" suffix:
|
63
|
+
|
64
|
+
``` ruby
|
65
|
+
category = Banyan::Category.first
|
66
|
+
category.my_model_categorizations # => []
|
67
|
+
```
|
68
|
+
|
69
|
+
You can change this behavior by by providing "as" options:
|
70
|
+
|
71
|
+
``` ruby
|
72
|
+
class MyModel < ActiveRecord::Base
|
73
|
+
acts_as_categorizable :as => "my_associations"
|
74
|
+
end
|
75
|
+
|
76
|
+
category = Banyan::Category.first
|
77
|
+
category.my_associations # => []
|
78
|
+
```
|
79
|
+
|
80
|
+
## Usage of Category Groups
|
81
|
+
|
82
|
+
Category Groups works with similar way that Categories. The main difference is that each CategoryGroup can have only one object attached(instead of collection for Category)
|
83
|
+
|
84
|
+
``` ruby
|
85
|
+
class MyModel < ActiveRecord::Base
|
86
|
+
acts_as_group_categorizable
|
87
|
+
end
|
88
|
+
|
89
|
+
my_model = MyModel.first
|
90
|
+
|
91
|
+
category_group = Banyan::CategoryGroup.first
|
92
|
+
category_group.group_categorizable # => nil
|
93
|
+
category_group.group_categorizable = my_model
|
94
|
+
|
95
|
+
my_model.category_groups # => [category_group]
|
96
|
+
```
|
97
|
+
|
98
|
+
Banyan::CategoryGroup have exactly the same attributes as Banyan::Category(see earlier).
|
99
|
+
|
100
|
+
## License
|
101
|
+
|
102
|
+
Banyan is released under the [MIT license](http://www.opensource.org/licenses/MIT).
|
data/Rakefile
ADDED
data/banyan.gemspec
ADDED
@@ -0,0 +1,25 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
$:.push File.expand_path("../lib", __FILE__)
|
3
|
+
require "banyan/version"
|
4
|
+
|
5
|
+
Gem::Specification.new do |s|
|
6
|
+
s.name = "banyan"
|
7
|
+
s.summary = "Pluggable categories and category groups to ActiveRecord models"
|
8
|
+
s.version = Banyan::VERSION
|
9
|
+
s.platform = Gem::Platform::RUBY
|
10
|
+
s.authors = ["Bernard Potocki", "Caleb Buxton"]
|
11
|
+
s.email = ["bernard.potocki@rebased.pl", "me@cpb.ca"]
|
12
|
+
|
13
|
+
s.add_dependency 'rails', '~> 3.0'
|
14
|
+
s.add_dependency 'globalize3', '~> 0.3'
|
15
|
+
s.add_dependency 'awesome_nested_set', '~> 2.0'
|
16
|
+
s.add_development_dependency 'sqlite3', '~> 1.3'
|
17
|
+
s.add_development_dependency 'rspec-rails', '~> 2.6'
|
18
|
+
s.add_development_dependency 'factory_girl', '~> 4.2'
|
19
|
+
s.add_development_dependency 'database_cleaner', '< 1.1.0'
|
20
|
+
|
21
|
+
s.files = `git ls-files`.split("\n")
|
22
|
+
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
23
|
+
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
24
|
+
s.require_paths = ["lib"]
|
25
|
+
end
|
@@ -0,0 +1,42 @@
|
|
1
|
+
module Banyan
|
2
|
+
module Categorizable
|
3
|
+
def self.included(base)
|
4
|
+
base.extend(ClassMethods)
|
5
|
+
end
|
6
|
+
|
7
|
+
module ClassMethods
|
8
|
+
# Add categories to model
|
9
|
+
# @param [Hash] opts Options for connection with categories
|
10
|
+
# @option opts [Boolean] :single Should categories be connected via has_one instead of has_many? Default: false
|
11
|
+
# @option opts [String] :as Association under which category will handle specified categoriable list. Default: class_name.underscore.gsub('/','___') + '_categorizations'
|
12
|
+
def acts_as_categorizable(opts = {})
|
13
|
+
single = !!opts.delete(:single)
|
14
|
+
as = opts.delete(:as) || (self.name.underscore.gsub('/','___') + '_categorizations')
|
15
|
+
|
16
|
+
if single
|
17
|
+
has_one :categorization, :as => :categorizable, :class_name => "::Banyan::Categorization", :dependent => :destroy
|
18
|
+
has_one :category, opts.merge(:through => :categorization)
|
19
|
+
else
|
20
|
+
has_many :categorizations, :as => :categorizable, :class_name => "::Banyan::Categorization", :dependent => :destroy
|
21
|
+
has_many :categories, opts.merge(:through => :categorizations, :uniq => true)
|
22
|
+
end
|
23
|
+
|
24
|
+
Banyan::Category.has_many as, :through => :categorizations, :source => :categorizable, :source_type => self.name
|
25
|
+
end
|
26
|
+
|
27
|
+
# Add category groups to model
|
28
|
+
# @param [Hash] opts Options for connection with category groups
|
29
|
+
# @option opts [Boolean] :single Should groups be connected via has_one instead of has_many? Default: false
|
30
|
+
def acts_as_group_categorizable(opts = {})
|
31
|
+
single = !!opts.delete(:single)
|
32
|
+
|
33
|
+
if single
|
34
|
+
has_one :category_group, opts.merge(:as => :group_categorizable, :class_name => "Banyan::CategoryGroup")
|
35
|
+
else
|
36
|
+
has_many :category_groups, opts.merge(:as => :group_categorizable, :class_name => "Banyan::CategoryGroup", :uniq => true)
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
end
|
42
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
module Banyan
|
2
|
+
class Category < ActiveRecord::Base
|
3
|
+
set_table_name 'banyan_categories'
|
4
|
+
|
5
|
+
acts_as_nested_set
|
6
|
+
translates :name
|
7
|
+
|
8
|
+
has_many :categorizations, :class_name => 'Banyan::Categorization', :dependent => :destroy
|
9
|
+
has_and_belongs_to_many :category_groups, :class_name => 'Banyan::CategoryGroup', :join_table => 'banyan_categories_category_groups', :include => :translations
|
10
|
+
|
11
|
+
validates_presence_of :name
|
12
|
+
|
13
|
+
attr_accessible :name, :tag
|
14
|
+
|
15
|
+
before_save :set_tag, :unless => :tag?
|
16
|
+
|
17
|
+
private
|
18
|
+
|
19
|
+
def set_tag
|
20
|
+
self.tag = name
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
module Banyan
|
2
|
+
class CategoryGroup < ActiveRecord::Base
|
3
|
+
set_table_name 'banyan_category_groups'
|
4
|
+
|
5
|
+
acts_as_nested_set
|
6
|
+
translates :name
|
7
|
+
|
8
|
+
belongs_to :group_categorizable, :polymorphic => true
|
9
|
+
has_and_belongs_to_many :categories, :class_name => 'Banyan::Category', :join_table => 'banyan_categories_category_groups', :include => :translations
|
10
|
+
|
11
|
+
validates_presence_of :name
|
12
|
+
|
13
|
+
attr_accessible :name, :tag
|
14
|
+
|
15
|
+
before_save :set_tag, :unless => :tag?
|
16
|
+
|
17
|
+
private
|
18
|
+
|
19
|
+
def set_tag
|
20
|
+
self.tag = name
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
data/lib/banyan.rb
ADDED
@@ -0,0 +1,13 @@
|
|
1
|
+
require 'awesome_nested_set'
|
2
|
+
require 'globalize3'
|
3
|
+
|
4
|
+
module Banyan
|
5
|
+
ROOT = File.expand_path(File.dirname(__FILE__))
|
6
|
+
|
7
|
+
autoload :Categorizable, "#{ROOT}/banyan/categorizable"
|
8
|
+
autoload :Categorization, "#{ROOT}/banyan/categorization"
|
9
|
+
autoload :Category, "#{ROOT}/banyan/category"
|
10
|
+
autoload :CategoryGroup, "#{ROOT}/banyan/category_group"
|
11
|
+
end
|
12
|
+
|
13
|
+
ActiveRecord::Base.class_eval { include Banyan::Categorizable }
|
@@ -0,0 +1,20 @@
|
|
1
|
+
require 'rails/generators/migration'
|
2
|
+
require 'rails/generators/active_record'
|
3
|
+
|
4
|
+
class BanyanGenerator < Rails::Generators::Base
|
5
|
+
include Rails::Generators::Migration
|
6
|
+
|
7
|
+
desc "Generates a migration for the Banyan"
|
8
|
+
|
9
|
+
def self.source_root
|
10
|
+
@source_root ||= File.dirname(__FILE__) + '/templates'
|
11
|
+
end
|
12
|
+
|
13
|
+
def self.next_migration_number(path)
|
14
|
+
ActiveRecord::Generators::Base.next_migration_number(path)
|
15
|
+
end
|
16
|
+
|
17
|
+
def generate_migration
|
18
|
+
migration_template 'migration.rb', 'db/migrate/create_banyan_tables'
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,54 @@
|
|
1
|
+
class CreateBanyanTables < ActiveRecord::Migration
|
2
|
+
def self.up
|
3
|
+
create_table :banyan_categories do |t|
|
4
|
+
t.string :tag
|
5
|
+
t.integer :parent_id
|
6
|
+
t.integer :lft
|
7
|
+
t.integer :rgt
|
8
|
+
end
|
9
|
+
add_index :banyan_categories, :tag
|
10
|
+
add_index :banyan_categories, :parent_id
|
11
|
+
add_index :banyan_categories, :lft
|
12
|
+
add_index :banyan_categories, :rgt
|
13
|
+
|
14
|
+
create_table :banyan_categories_category_groups, :id => false do |t|
|
15
|
+
t.integer :category_id
|
16
|
+
t.integer :category_group_id
|
17
|
+
end
|
18
|
+
execute "ALTER TABLE banyan_categories_category_groups ADD PRIMARY KEY (category_id, category_group_id);"
|
19
|
+
add_index :banyan_categories_category_groups, :category_group_id
|
20
|
+
|
21
|
+
create_table :banyan_categorizations do |t|
|
22
|
+
t.integer :category_id
|
23
|
+
t.references :categorizable, :polymorphic => true
|
24
|
+
end
|
25
|
+
add_index :banyan_categorizations, :category_id
|
26
|
+
add_index :banyan_categorizations, [:categorizable_id, :categorizable_type], :name => 'index_banyan_categorizations_on_categorizable'
|
27
|
+
|
28
|
+
create_table :banyan_category_groups do |t|
|
29
|
+
t.string :tag
|
30
|
+
t.references :group_categorizable, :polymorphic => true
|
31
|
+
t.integer :parent_id
|
32
|
+
t.integer :lft
|
33
|
+
t.integer :rgt
|
34
|
+
end
|
35
|
+
add_index :banyan_category_groups, :tag
|
36
|
+
add_index :banyan_category_groups, [:group_categorizable_id, :group_categorizable_type], :name => 'index_banyan_category_groups_on_group_categorizable'
|
37
|
+
add_index :banyan_category_groups, :parent_id
|
38
|
+
add_index :banyan_category_groups, :lft
|
39
|
+
add_index :banyan_category_groups, :rgt
|
40
|
+
|
41
|
+
Banyan::Category.create_translation_table! :name => :string
|
42
|
+
Banyan::CategoryGroup.create_translation_table! :name => :string
|
43
|
+
end
|
44
|
+
|
45
|
+
def self.down
|
46
|
+
drop_table :banyan_category_groups
|
47
|
+
drop_table :banyan_categorizations
|
48
|
+
drop_table :banyan_categories_category_groups
|
49
|
+
drop_table :banyan_categories
|
50
|
+
|
51
|
+
Banyan::Category.drop_translation_table!
|
52
|
+
Banyan::CategoryGroup.drop_translation_table!
|
53
|
+
end
|
54
|
+
end
|
@@ -0,0 +1,62 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Banyan::CategoryGroup do
|
4
|
+
let(:category_group) { FactoryGirl.create(:banyan_category_group) }
|
5
|
+
subject { category_group }
|
6
|
+
|
7
|
+
it { should be_valid }
|
8
|
+
its(:children) { should be_empty }
|
9
|
+
its(:group_categorizable) { should be_nil }
|
10
|
+
|
11
|
+
context "with banyan group model created" do
|
12
|
+
let(:banyan_group_model) { FactoryGirl.create :banyan_group_model }
|
13
|
+
before { subject.group_categorizable = banyan_group_model; subject.save }
|
14
|
+
|
15
|
+
its(:group_categorizable) { should eql(banyan_group_model) }
|
16
|
+
it "should be visible by banyan group model" do
|
17
|
+
banyan_group_model.category_groups.should include(subject)
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
context "with children" do
|
22
|
+
let(:subcategory) { FactoryGirl.create :banyan_category_group }
|
23
|
+
before { subject.children << subcategory }
|
24
|
+
|
25
|
+
its(:children) { should include(subcategory) }
|
26
|
+
it "should be visible from subcategory" do
|
27
|
+
subcategory.parent.should eql(subject)
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
context "in different language" do
|
32
|
+
before do
|
33
|
+
@default_language = I18n.locale
|
34
|
+
@default_name = subject.name
|
35
|
+
I18n.locale = :es
|
36
|
+
end
|
37
|
+
after { I18n.locale = @default_locale }
|
38
|
+
|
39
|
+
its(:name) { should eql(@default_name) }
|
40
|
+
it "should be able to change name" do
|
41
|
+
subject.name = "test"
|
42
|
+
subject.name.should eql("test")
|
43
|
+
I18n.locale = @default_locale
|
44
|
+
subject.name.should eql(@default_name)
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
context "#tag" do
|
49
|
+
subject { category_group.tag }
|
50
|
+
|
51
|
+
context "when not explicitly set" do
|
52
|
+
it { should eq(category_group.name) }
|
53
|
+
end
|
54
|
+
|
55
|
+
context "when explicitly set" do
|
56
|
+
let(:tag_name) { 'foobar' }
|
57
|
+
let(:category_group) { FactoryGirl.create(:banyan_category_group, :tag => tag_name) }
|
58
|
+
|
59
|
+
it { should eq(tag_name) }
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
@@ -0,0 +1,62 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Banyan::Category do
|
4
|
+
let(:category) { FactoryGirl.create(:banyan_category) }
|
5
|
+
subject { category }
|
6
|
+
|
7
|
+
it { should be_valid }
|
8
|
+
its(:children) { should be_empty }
|
9
|
+
its(:banyan_model_categorizations) { should be_empty }
|
10
|
+
|
11
|
+
context "with banyan model created" do
|
12
|
+
let(:banyan_model) { FactoryGirl.create :banyan_model }
|
13
|
+
before { subject.banyan_model_categorizations << banyan_model }
|
14
|
+
|
15
|
+
its(:banyan_model_categorizations) { should include(banyan_model) }
|
16
|
+
it "should be visible by banyan model" do
|
17
|
+
banyan_model.categories.should include(subject)
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
context "with children" do
|
22
|
+
let(:subcategory) { FactoryGirl.create :banyan_category }
|
23
|
+
before { subject.children << subcategory }
|
24
|
+
|
25
|
+
its(:children) { should include(subcategory) }
|
26
|
+
it "should be visible from subcategory" do
|
27
|
+
subcategory.parent.should eql(subject)
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
context "in different language" do
|
32
|
+
before do
|
33
|
+
@default_language = I18n.locale
|
34
|
+
@default_name = subject.name
|
35
|
+
I18n.locale = :es
|
36
|
+
end
|
37
|
+
after { I18n.locale = @default_locale }
|
38
|
+
|
39
|
+
its(:name) { should eql(@default_name) }
|
40
|
+
it "should be able to change name" do
|
41
|
+
subject.name = "test"
|
42
|
+
subject.name.should eql("test")
|
43
|
+
I18n.locale = @default_locale
|
44
|
+
subject.name.should eql(@default_name)
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
context "#tag" do
|
49
|
+
subject { category.tag }
|
50
|
+
|
51
|
+
context "when not explicitly set" do
|
52
|
+
it { should eq(category.name) }
|
53
|
+
end
|
54
|
+
|
55
|
+
context "when explicitly set" do
|
56
|
+
let(:tag_name) { 'foobar' }
|
57
|
+
let(:category) { FactoryGirl.create(:banyan_category, :tag => tag_name) }
|
58
|
+
|
59
|
+
it { should eq(tag_name) }
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Banyan::BanyanGroupModel do
|
4
|
+
subject { FactoryGirl.create :banyan_group_model }
|
5
|
+
|
6
|
+
it { should be_valid }
|
7
|
+
its(:category_groups) { should be_an(Array) }
|
8
|
+
its(:category_groups) { should be_empty }
|
9
|
+
|
10
|
+
context "with category group created" do
|
11
|
+
let(:category_group) { FactoryGirl.create :banyan_category_group }
|
12
|
+
before do
|
13
|
+
subject.category_groups << category_group
|
14
|
+
subject.reload
|
15
|
+
end
|
16
|
+
|
17
|
+
it "should return only one instance of a category group" do
|
18
|
+
subject.category_groups << category_group
|
19
|
+
subject.category_groups << category_group
|
20
|
+
subject.category_groups.should have(1).item
|
21
|
+
end
|
22
|
+
|
23
|
+
its(:category_groups) { should include(category_group) }
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Banyan::BanyanModel do
|
4
|
+
let(:timestamp) { 1.day.ago }
|
5
|
+
subject { FactoryGirl.create :banyan_model, :updated_at => timestamp }
|
6
|
+
|
7
|
+
it { should be_valid }
|
8
|
+
its('categories.class') { should eql(Array) }
|
9
|
+
its(:categories) { should be_empty }
|
10
|
+
|
11
|
+
context "with category created" do
|
12
|
+
let(:category) { FactoryGirl.create :banyan_category }
|
13
|
+
|
14
|
+
before do
|
15
|
+
subject.categories << category
|
16
|
+
subject.reload
|
17
|
+
end
|
18
|
+
|
19
|
+
its(:categories) { should include(category) }
|
20
|
+
its(:updated_at) { should be > timestamp }
|
21
|
+
it "should be visible from category" do
|
22
|
+
category.banyan_model_categorizations.should include(subject)
|
23
|
+
end
|
24
|
+
|
25
|
+
it "should return only one instance of a category" do
|
26
|
+
subject.categories << category
|
27
|
+
subject.categories.should have(1).item
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Banyan::BanyanSingleGroupModel do
|
4
|
+
subject { FactoryGirl.create :banyan_single_group_model }
|
5
|
+
|
6
|
+
it { should be_valid }
|
7
|
+
its(:category_group) { should be_nil }
|
8
|
+
|
9
|
+
context "with category group created" do
|
10
|
+
let(:category_group) { FactoryGirl.create :banyan_category_group }
|
11
|
+
before do
|
12
|
+
subject.category_group = category_group
|
13
|
+
subject.reload
|
14
|
+
end
|
15
|
+
|
16
|
+
its(:category_group) { should eq(category_group) }
|
17
|
+
end
|
18
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,37 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'active_support'
|
3
|
+
require 'active_record'
|
4
|
+
require 'action_controller'
|
5
|
+
require 'action_view'
|
6
|
+
|
7
|
+
require 'rspec/core'
|
8
|
+
require 'rspec/rails'
|
9
|
+
require 'database_cleaner'
|
10
|
+
require 'factory_girl'
|
11
|
+
|
12
|
+
# This is optional for end-user
|
13
|
+
require "i18n/backend/fallbacks"
|
14
|
+
I18n::Backend::Simple.send(:include, I18n::Backend::Fallbacks)
|
15
|
+
|
16
|
+
require 'banyan'
|
17
|
+
|
18
|
+
Dir["#{File.dirname(__FILE__)}/support/**/*.rb"].each {|f| require f}
|
19
|
+
Dir["#{File.dirname(__FILE__)}/factories/**/*.rb"].each {|f| require f}
|
20
|
+
|
21
|
+
RSpec.configure do |config|
|
22
|
+
|
23
|
+
config.before(:suite) do
|
24
|
+
DatabaseCleaner.strategy = :transaction
|
25
|
+
DatabaseCleaner.clean_with(:truncation)
|
26
|
+
end
|
27
|
+
|
28
|
+
config.before(:each) do
|
29
|
+
DatabaseCleaner.start
|
30
|
+
end
|
31
|
+
|
32
|
+
config.after(:each) do
|
33
|
+
DatabaseCleaner.clean
|
34
|
+
end
|
35
|
+
|
36
|
+
end
|
37
|
+
|
@@ -0,0 +1,49 @@
|
|
1
|
+
ActiveRecord::Base.establish_connection(:adapter => "sqlite3", :database => ":memory:")
|
2
|
+
|
3
|
+
ActiveRecord::Schema.define(:version => 1) do
|
4
|
+
|
5
|
+
create_table :banyan_categories do |t|
|
6
|
+
t.string :tag
|
7
|
+
t.integer :parent_id
|
8
|
+
t.integer :lft
|
9
|
+
t.integer :rgt
|
10
|
+
end
|
11
|
+
|
12
|
+
create_table :banyan_categories_category_groups, :id => false do |t|
|
13
|
+
t.integer :category_id
|
14
|
+
t.integer :category_group_id
|
15
|
+
end
|
16
|
+
|
17
|
+
create_table :banyan_categorizations do |t|
|
18
|
+
t.integer :category_id
|
19
|
+
t.integer :categorizable_id
|
20
|
+
t.string :categorizable_type
|
21
|
+
end
|
22
|
+
|
23
|
+
create_table :banyan_category_groups do |t|
|
24
|
+
t.string :tag
|
25
|
+
t.integer :group_categorizable_id
|
26
|
+
t.string :group_categorizable_type
|
27
|
+
t.integer :parent_id
|
28
|
+
t.integer :lft
|
29
|
+
t.integer :rgt
|
30
|
+
end
|
31
|
+
|
32
|
+
Banyan::Category.create_translation_table! :name => :string
|
33
|
+
Banyan::CategoryGroup.create_translation_table! :name => :string
|
34
|
+
|
35
|
+
add_index :banyan_categories, :tag, :unique => true
|
36
|
+
add_index :banyan_category_groups, :tag, :unique => true
|
37
|
+
|
38
|
+
create_table :banyan_models do |t|
|
39
|
+
t.integer :banyan_group_model_id
|
40
|
+
t.timestamps
|
41
|
+
end
|
42
|
+
|
43
|
+
create_table :banyan_group_models do |t|
|
44
|
+
end
|
45
|
+
|
46
|
+
create_table :banyan_single_group_models do |t|
|
47
|
+
end
|
48
|
+
|
49
|
+
end
|
metadata
ADDED
@@ -0,0 +1,187 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: banyan
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 1.0.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Bernard Potocki
|
8
|
+
- Caleb Buxton
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2013-09-18 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: rails
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
17
|
+
requirements:
|
18
|
+
- - ~>
|
19
|
+
- !ruby/object:Gem::Version
|
20
|
+
version: '3.0'
|
21
|
+
type: :runtime
|
22
|
+
prerelease: false
|
23
|
+
version_requirements: !ruby/object:Gem::Requirement
|
24
|
+
requirements:
|
25
|
+
- - ~>
|
26
|
+
- !ruby/object:Gem::Version
|
27
|
+
version: '3.0'
|
28
|
+
- !ruby/object:Gem::Dependency
|
29
|
+
name: globalize3
|
30
|
+
requirement: !ruby/object:Gem::Requirement
|
31
|
+
requirements:
|
32
|
+
- - ~>
|
33
|
+
- !ruby/object:Gem::Version
|
34
|
+
version: '0.3'
|
35
|
+
type: :runtime
|
36
|
+
prerelease: false
|
37
|
+
version_requirements: !ruby/object:Gem::Requirement
|
38
|
+
requirements:
|
39
|
+
- - ~>
|
40
|
+
- !ruby/object:Gem::Version
|
41
|
+
version: '0.3'
|
42
|
+
- !ruby/object:Gem::Dependency
|
43
|
+
name: awesome_nested_set
|
44
|
+
requirement: !ruby/object:Gem::Requirement
|
45
|
+
requirements:
|
46
|
+
- - ~>
|
47
|
+
- !ruby/object:Gem::Version
|
48
|
+
version: '2.0'
|
49
|
+
type: :runtime
|
50
|
+
prerelease: false
|
51
|
+
version_requirements: !ruby/object:Gem::Requirement
|
52
|
+
requirements:
|
53
|
+
- - ~>
|
54
|
+
- !ruby/object:Gem::Version
|
55
|
+
version: '2.0'
|
56
|
+
- !ruby/object:Gem::Dependency
|
57
|
+
name: sqlite3
|
58
|
+
requirement: !ruby/object:Gem::Requirement
|
59
|
+
requirements:
|
60
|
+
- - ~>
|
61
|
+
- !ruby/object:Gem::Version
|
62
|
+
version: '1.3'
|
63
|
+
type: :development
|
64
|
+
prerelease: false
|
65
|
+
version_requirements: !ruby/object:Gem::Requirement
|
66
|
+
requirements:
|
67
|
+
- - ~>
|
68
|
+
- !ruby/object:Gem::Version
|
69
|
+
version: '1.3'
|
70
|
+
- !ruby/object:Gem::Dependency
|
71
|
+
name: rspec-rails
|
72
|
+
requirement: !ruby/object:Gem::Requirement
|
73
|
+
requirements:
|
74
|
+
- - ~>
|
75
|
+
- !ruby/object:Gem::Version
|
76
|
+
version: '2.6'
|
77
|
+
type: :development
|
78
|
+
prerelease: false
|
79
|
+
version_requirements: !ruby/object:Gem::Requirement
|
80
|
+
requirements:
|
81
|
+
- - ~>
|
82
|
+
- !ruby/object:Gem::Version
|
83
|
+
version: '2.6'
|
84
|
+
- !ruby/object:Gem::Dependency
|
85
|
+
name: factory_girl
|
86
|
+
requirement: !ruby/object:Gem::Requirement
|
87
|
+
requirements:
|
88
|
+
- - ~>
|
89
|
+
- !ruby/object:Gem::Version
|
90
|
+
version: '4.2'
|
91
|
+
type: :development
|
92
|
+
prerelease: false
|
93
|
+
version_requirements: !ruby/object:Gem::Requirement
|
94
|
+
requirements:
|
95
|
+
- - ~>
|
96
|
+
- !ruby/object:Gem::Version
|
97
|
+
version: '4.2'
|
98
|
+
- !ruby/object:Gem::Dependency
|
99
|
+
name: database_cleaner
|
100
|
+
requirement: !ruby/object:Gem::Requirement
|
101
|
+
requirements:
|
102
|
+
- - <
|
103
|
+
- !ruby/object:Gem::Version
|
104
|
+
version: 1.1.0
|
105
|
+
type: :development
|
106
|
+
prerelease: false
|
107
|
+
version_requirements: !ruby/object:Gem::Requirement
|
108
|
+
requirements:
|
109
|
+
- - <
|
110
|
+
- !ruby/object:Gem::Version
|
111
|
+
version: 1.1.0
|
112
|
+
description:
|
113
|
+
email:
|
114
|
+
- bernard.potocki@rebased.pl
|
115
|
+
- me@cpb.ca
|
116
|
+
executables: []
|
117
|
+
extensions: []
|
118
|
+
extra_rdoc_files: []
|
119
|
+
files:
|
120
|
+
- .gitignore
|
121
|
+
- Gemfile
|
122
|
+
- MIT-LICENSE
|
123
|
+
- README.md
|
124
|
+
- Rakefile
|
125
|
+
- banyan.gemspec
|
126
|
+
- lib/banyan.rb
|
127
|
+
- lib/banyan/categorizable.rb
|
128
|
+
- lib/banyan/categorization.rb
|
129
|
+
- lib/banyan/category.rb
|
130
|
+
- lib/banyan/category_group.rb
|
131
|
+
- lib/banyan/version.rb
|
132
|
+
- lib/generators/banyan/banyan_generator.rb
|
133
|
+
- lib/generators/banyan/templates/migration.rb
|
134
|
+
- spec/banyan/banyan_category_group_spec.rb
|
135
|
+
- spec/banyan/banyan_category_spec.rb
|
136
|
+
- spec/banyan/banyan_group_model_spec.rb
|
137
|
+
- spec/banyan/banyan_model_spec.rb
|
138
|
+
- spec/banyan/banyan_single_group_model_spec.rb
|
139
|
+
- spec/factories/banyan_category.rb
|
140
|
+
- spec/factories/banyan_category_group.rb
|
141
|
+
- spec/factories/banyan_group_model.rb
|
142
|
+
- spec/factories/banyan_model.rb
|
143
|
+
- spec/factories/banyan_single_group_model.rb
|
144
|
+
- spec/spec_helper.rb
|
145
|
+
- spec/support/00_schema.rb
|
146
|
+
- spec/support/banyan_group_model.rb
|
147
|
+
- spec/support/banyan_model.rb
|
148
|
+
- spec/support/banyan_single_group_model.rb
|
149
|
+
homepage:
|
150
|
+
licenses: []
|
151
|
+
metadata: {}
|
152
|
+
post_install_message:
|
153
|
+
rdoc_options: []
|
154
|
+
require_paths:
|
155
|
+
- lib
|
156
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
157
|
+
requirements:
|
158
|
+
- - ! '>='
|
159
|
+
- !ruby/object:Gem::Version
|
160
|
+
version: '0'
|
161
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
162
|
+
requirements:
|
163
|
+
- - ! '>='
|
164
|
+
- !ruby/object:Gem::Version
|
165
|
+
version: '0'
|
166
|
+
requirements: []
|
167
|
+
rubyforge_project:
|
168
|
+
rubygems_version: 2.0.4
|
169
|
+
signing_key:
|
170
|
+
specification_version: 4
|
171
|
+
summary: Pluggable categories and category groups to ActiveRecord models
|
172
|
+
test_files:
|
173
|
+
- spec/banyan/banyan_category_group_spec.rb
|
174
|
+
- spec/banyan/banyan_category_spec.rb
|
175
|
+
- spec/banyan/banyan_group_model_spec.rb
|
176
|
+
- spec/banyan/banyan_model_spec.rb
|
177
|
+
- spec/banyan/banyan_single_group_model_spec.rb
|
178
|
+
- spec/factories/banyan_category.rb
|
179
|
+
- spec/factories/banyan_category_group.rb
|
180
|
+
- spec/factories/banyan_group_model.rb
|
181
|
+
- spec/factories/banyan_model.rb
|
182
|
+
- spec/factories/banyan_single_group_model.rb
|
183
|
+
- spec/spec_helper.rb
|
184
|
+
- spec/support/00_schema.rb
|
185
|
+
- spec/support/banyan_group_model.rb
|
186
|
+
- spec/support/banyan_model.rb
|
187
|
+
- spec/support/banyan_single_group_model.rb
|