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 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
@@ -0,0 +1,3 @@
1
+ source "http://rubygems.org"
2
+
3
+ gemspec
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
@@ -0,0 +1,12 @@
1
+ require "bundler/gem_tasks"
2
+ require 'rake'
3
+
4
+ require 'rspec/core'
5
+ require 'rspec/core/rake_task'
6
+
7
+ RSpec::Core::RakeTask.new do |t|
8
+ t.rspec_opts = ["-c", "-f progress"]
9
+ t.pattern = 'spec/**/*_spec.rb'
10
+ end
11
+
12
+ task :default => :spec
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,9 @@
1
+ module Banyan
2
+ class Categorization < ActiveRecord::Base
3
+ set_table_name 'banyan_categorizations'
4
+
5
+ belongs_to :category, :class_name => 'Banyan::Category'
6
+ belongs_to :categorizable, :polymorphic => true, :touch => true
7
+
8
+ end
9
+ 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
@@ -0,0 +1,3 @@
1
+ module Banyan
2
+ VERSION = '1.0.1'
3
+ 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
@@ -0,0 +1,5 @@
1
+ FactoryGirl.define do
2
+ factory :banyan_category, :class => 'Banyan::Category' do |f|
3
+ f.sequence(:name) { |n| "Category #{n}" }
4
+ end
5
+ end
@@ -0,0 +1,5 @@
1
+ FactoryGirl.define do
2
+ factory :banyan_category_group, :class => 'Banyan::CategoryGroup' do |f|
3
+ f.sequence(:name) { |n| "Category Group #{n}" }
4
+ end
5
+ end
@@ -0,0 +1,4 @@
1
+ FactoryGirl.define do
2
+ factory :banyan_group_model, :class => 'Banyan::BanyanGroupModel' do |f|
3
+ end
4
+ end
@@ -0,0 +1,5 @@
1
+ FactoryGirl.define do
2
+ factory :banyan_model, :class => 'Banyan::BanyanModel' do |f|
3
+ f.association :banyan_group_model, :factory => :banyan_group_model
4
+ end
5
+ end
@@ -0,0 +1,4 @@
1
+ FactoryGirl.define do
2
+ factory :banyan_single_group_model, :class => 'Banyan::BanyanSingleGroupModel' do |f|
3
+ end
4
+ end
@@ -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
@@ -0,0 +1,5 @@
1
+ class Banyan::BanyanGroupModel < ActiveRecord::Base
2
+ acts_as_group_categorizable
3
+
4
+ has_many :banyan_models, :class_name => 'Banyan::BanyanModel'
5
+ end
@@ -0,0 +1,5 @@
1
+ class Banyan::BanyanModel < ActiveRecord::Base
2
+ acts_as_categorizable :as => :banyan_model_categorizations
3
+
4
+ belongs_to :banyan_group_model, :class_name => 'Banyan::BanyanGroupModel'
5
+ end
@@ -0,0 +1,3 @@
1
+ class Banyan::BanyanSingleGroupModel < ActiveRecord::Base
2
+ acts_as_group_categorizable :single => true
3
+ 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