ordered_tree 0.1.1 → 0.1.2

Sign up to get free protection for your applications and to get access to all the features.
data/README.textile CHANGED
@@ -33,8 +33,8 @@ v.1.2
33
33
 
34
34
  <pre>
35
35
  class Person < ActiveRecord::Base
36
- acts_as_ordered_tree :foreign_key => :parent_id,
37
- :order => :position
36
+ ordered_tree :foreign_key => :parent_id,
37
+ :order => :position
38
38
  end
39
39
 
40
40
  class CreatePeople < ActiveRecord::Migration
@@ -61,6 +61,8 @@ has_many :children,
61
61
  :order => :position
62
62
  </pre>
63
63
 
64
+ _Note: @:parent_id@ and @:position@ are default values for the @foreign_key@ and @order@, respectively._
65
+
64
66
  h2. Overview
65
67
 
66
68
  <pre>
@@ -111,13 +113,47 @@ h2. Overview
111
113
  destroy_and_orphan_children
112
114
 
113
115
  destroy_and_parent_adopts_children
114
-
115
116
  </pre>
116
117
 
117
- h2. Install
118
+ h2. Setting the scope
118
119
 
119
- gem 'ordered_tree'
120
+ If you want to have multiple trees in the same database (let's say you want to have multiple sets of pages for the different tenants on your database), you should set a scope. A scope basically says: "work within this scope when possible".
121
+
122
+ How does it work?
123
+
124
+ Let's say I have a multi-tenant CMS app. I want each site to have their own Page tree. So Page uses @ordered_tree :scope => :site@ so that when I do this:
125
+
126
+ pre. @site_1 = Site.create :name => "First site"
127
+ @site_2 = Site.create :name => "Second site"
128
+ Page.create(:site => @site_1).position # returns 1
129
+ Page.create(:site => @site_2).position # returns 1
130
+ Page.create(:site => @site_2).position # returns 2
131
+ Page.create(:site => @site_1).position # returns 2
132
+
133
+ Warning: @Page.roots@ will always return all the root pages (all pages with parent_id of 0). That's because there's no way to know which pages you want to see. That means, when you want to get a site's root pages, go through the site: @@site.pages.roots@
134
+
135
+ Here are all the ways to define the scope:
136
+
137
+ h3. Give a symbol without _id:
138
+
139
+ @ordered_tree :scope => :site@
120
140
 
121
- h2. Demo
141
+ @ordered_tree@ will add @_id@ to @:site@ so it becomes: @:site_id@
122
142
 
123
- There is a drag-n-drop demo located at svn://rubyforge.org/var/svn/ordered-tree/demo
143
+ Thus, you can also pass:
144
+
145
+ h3. Give a symbol with _id
146
+
147
+ @ordered_tree :scope => :site_id@
148
+
149
+ h3. Override the scope_condition method
150
+
151
+ For more complex stuff, in the model that has @ordered_tree@, define a method like this:
152
+
153
+ pre. def scope_condition
154
+ "site_id = #{site_id} AND user_login = '#{user_login}'"
155
+ end
156
+
157
+ h2. Install
158
+
159
+ gem 'ordered_tree'
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.1.1
1
+ 0.1.2
@@ -1,12 +1,7 @@
1
1
  module OrderedTree
2
2
  module ClassMethods
3
3
  extend ActiveSupport::Concern
4
-
5
4
  included do
6
- belongs_to :parent_node, :class_name => name, :foreign_key => ordered_tree_config[:foreign_key]
7
- has_many :child_nodes, :class_name => name, :foreign_key => ordered_tree_config[:foreign_key], :order => ordered_tree_config[:order]
8
- scope :roots, lambda { { :conditions => {ordered_tree_config[:foreign_key] => 0}, :order => ordered_tree_config[:order].to_s } }
9
-
10
5
  def foreign_key_column
11
6
  :"#{ordered_tree_config[:foreign_key]}"
12
7
  end
@@ -8,7 +8,8 @@ module OrderedTree
8
8
  # return is cached
9
9
  # use self_and_siblings(true) to force a reload
10
10
  def self_and_siblings(reload = false)
11
- parent(reload) ? parent.children(reload) : self.class.roots(reload)
11
+ #parent(reload) ? parent.children(reload) : self.class.roots(scope_condition)
12
+ parent(reload) ? parent.children(reload) : self.class.roots(scope_condition)
12
13
  end
13
14
 
14
15
  # returns an array of the object's siblings, excluding itself
@@ -10,6 +10,13 @@ module OrderedTree
10
10
  def order_column
11
11
  :"#{ordered_tree_config[:order]}"
12
12
  end
13
+
14
+ private
15
+
16
+ # Overwrite this method to define the scope of the list changes
17
+ def scope_condition
18
+ "1"
19
+ end
13
20
  end
14
21
  end
15
22
  end
data/lib/ordered_tree.rb CHANGED
@@ -25,6 +25,25 @@ module OrderedTree #:nodoc:
25
25
  self.ordered_tree_config[:foreign_key] ||= :parent_id
26
26
  self.ordered_tree_config[:order] ||= :position
27
27
  self.ordered_tree_config.update(options) if options.is_a?(Hash)
28
+
29
+ belongs_to :parent_node, :class_name => self.name, :foreign_key => ordered_tree_config[:foreign_key]
30
+ has_many :child_nodes, :class_name => self.name, :foreign_key => ordered_tree_config[:foreign_key], :order => ordered_tree_config[:order]
31
+ scope :roots, lambda { |*args|
32
+ scope_condition = args[0]
33
+ where(self.ordered_tree_config[:foreign_key].to_sym => 0).where(scope_condition).order(self.ordered_tree_config[:order])
34
+ }
35
+
36
+ # If the scope is something like :person, then turn it into :person_id
37
+ if self.ordered_tree_config[:scope].is_a?(Symbol) && self.ordered_tree_config[:scope].to_s !~ /_id$/
38
+ self.ordered_tree_config[:scope] = "#{self.ordered_tree_config[:scope]}_id".intern
39
+ end
40
+
41
+ if self.ordered_tree_config[:scope].is_a?(Symbol) # ie :person_id
42
+ define_method "scope_condition" do
43
+ self.class.send(:sanitize_sql_hash_for_conditions, {self.class.ordered_tree_config[:scope].to_sym => send(self.class.ordered_tree_config[:scope].to_sym)})
44
+ end
45
+ end
46
+
28
47
  include OrderedTree::ClassMethods
29
48
  include OrderedTree::InstanceMethods
30
49
  end #ordered_tree
data/ordered_tree.gemspec CHANGED
@@ -5,16 +5,15 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = %q{ordered_tree}
8
- s.version = "0.1.1"
8
+ s.version = "0.1.2"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
11
  s.authors = ["Ramon Tayag"]
12
- s.date = %q{2011-06-03}
12
+ s.date = %q{2011-06-13}
13
13
  s.description = %q{Uses parent_id and position to create an ordered tree.}
14
14
  s.email = %q{ramon@tayag.net}
15
15
  s.extra_rdoc_files = [
16
16
  "LICENSE.txt",
17
- "README.rdoc",
18
17
  "README.textile"
19
18
  ]
20
19
  s.files = [
@@ -24,7 +23,6 @@ Gem::Specification.new do |s|
24
23
  "Gemfile.lock",
25
24
  "Guardfile",
26
25
  "LICENSE.txt",
27
- "README.rdoc",
28
26
  "README.textile",
29
27
  "Rakefile",
30
28
  "VERSION",
@@ -36,6 +34,7 @@ Gem::Specification.new do |s|
36
34
  "lib/ordered_tree/instance_methods/misc.rb",
37
35
  "lib/ordered_tree/instance_methods/tree.rb",
38
36
  "ordered_tree.gemspec",
37
+ "spec/fixtures/page.rb",
39
38
  "spec/fixtures/person.rb",
40
39
  "spec/ordered_tree_spec.rb",
41
40
  "spec/spec_helper.rb"
@@ -0,0 +1,4 @@
1
+ class Page < ActiveRecord::Base
2
+ belongs_to :person
3
+ ordered_tree
4
+ end
@@ -1,3 +1,4 @@
1
1
  class Person < ActiveRecord::Base
2
+ has_many :pages
2
3
  ordered_tree
3
4
  end
@@ -6,6 +6,37 @@ describe OrderedTree do
6
6
  @people = Person.all
7
7
  end
8
8
 
9
+ describe "when a scope is supplied" do
10
+ # This is especially important for working with root items that may belong to different accounts
11
+ it "should only work within that scope" do
12
+ # when the scope is an association
13
+ ordered_tree Page, :scope => :person do
14
+ Page.create(:person => @people[0]).position.should == 1
15
+ Page.create(:person => @people[2]).position.should == 1
16
+ Page.create(:person => @people[0]).position.should == 2
17
+ Page.create(:person => @people[1]).position.should == 1
18
+ end
19
+
20
+ # when the scope is an association id
21
+ ordered_tree Page, :scope => :person_id do
22
+ Page.create(:person => @people[0]).position.should == 3
23
+ Page.create(:person => @people[2]).position.should == 2
24
+ Page.create(:person => @people[0]).position.should == 4
25
+ Page.create(:person => @people[1]).position.should == 2
26
+ end
27
+
28
+ # when the scope_condition method is overridden
29
+ Page.class_eval do
30
+ def scope_condition
31
+ "person_id = #{person_id} AND name = '#{name}'"
32
+ end
33
+ end
34
+ Page.create(:person => @people[3], :name => "frankenstein").position.should == 1
35
+ Page.create(:person => @people[3], :name => "steiners").position.should == 1
36
+ Page.create(:person => @people[3], :name => "frankenstein").position.should == 2
37
+ end
38
+ end
39
+
9
40
  describe "when assigning parent" do
10
41
  it "should do a bunch of tests on validation" do
11
42
  # "should not allow an ancestor of a node to be a child of that node"
data/spec/spec_helper.rb CHANGED
@@ -5,6 +5,7 @@ require 'active_record'
5
5
  require 'rspec'
6
6
  require 'ordered_tree'
7
7
  require 'spec/fixtures/person'
8
+ require 'spec/fixtures/page'
8
9
 
9
10
  #Allow to connect to SQLite
10
11
  ActiveRecord::Base.establish_connection(
@@ -20,7 +21,7 @@ RSpec.configure do |config|
20
21
  end
21
22
 
22
23
  def reset_database
23
- %W(people).each do |table_name|
24
+ %W(people pages).each do |table_name|
24
25
  ActiveRecord::Base.connection.execute("DROP TABLE IF EXISTS '#{table_name}'")
25
26
  end
26
27
  ActiveRecord::Base.connection.create_table(:people) do |t|
@@ -29,6 +30,12 @@ def reset_database
29
30
  t.string :name
30
31
  #add_index :people, [:parent_id], :name => "index_people_on_parent_id"
31
32
  end
33
+ ActiveRecord::Base.connection.create_table(:pages) do |t|
34
+ t.integer :parent_id, :null => false, :default => 0
35
+ t.integer :position
36
+ t.string :name
37
+ t.integer :person_id
38
+ end
32
39
  end
33
40
 
34
41
  def ordered_tree(klass, *opts)
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ordered_tree
3
3
  version: !ruby/object:Gem::Version
4
- hash: 25
4
+ hash: 31
5
5
  prerelease:
6
6
  segments:
7
7
  - 0
8
8
  - 1
9
- - 1
10
- version: 0.1.1
9
+ - 2
10
+ version: 0.1.2
11
11
  platform: ruby
12
12
  authors:
13
13
  - Ramon Tayag
@@ -15,7 +15,7 @@ autorequire:
15
15
  bindir: bin
16
16
  cert_chain: []
17
17
 
18
- date: 2011-06-03 00:00:00 +08:00
18
+ date: 2011-06-13 00:00:00 +08:00
19
19
  default_executable:
20
20
  dependencies:
21
21
  - !ruby/object:Gem::Dependency
@@ -160,7 +160,6 @@ extensions: []
160
160
 
161
161
  extra_rdoc_files:
162
162
  - LICENSE.txt
163
- - README.rdoc
164
163
  - README.textile
165
164
  files:
166
165
  - .rvmrc
@@ -169,7 +168,6 @@ files:
169
168
  - Gemfile.lock
170
169
  - Guardfile
171
170
  - LICENSE.txt
172
- - README.rdoc
173
171
  - README.textile
174
172
  - Rakefile
175
173
  - VERSION
@@ -181,6 +179,7 @@ files:
181
179
  - lib/ordered_tree/instance_methods/misc.rb
182
180
  - lib/ordered_tree/instance_methods/tree.rb
183
181
  - ordered_tree.gemspec
182
+ - spec/fixtures/page.rb
184
183
  - spec/fixtures/person.rb
185
184
  - spec/ordered_tree_spec.rb
186
185
  - spec/spec_helper.rb
data/README.rdoc DELETED
@@ -1,19 +0,0 @@
1
- = ordered_tree
2
-
3
- Description goes here.
4
-
5
- == Contributing to ordered_tree
6
-
7
- * Check out the latest master to make sure the feature hasn't been implemented or the bug hasn't been fixed yet
8
- * Check out the issue tracker to make sure someone already hasn't requested it and/or contributed it
9
- * Fork the project
10
- * Start a feature/bugfix branch
11
- * Commit and push until you are happy with your contribution
12
- * Make sure to add tests for it. This is important so I don't break it in a future version unintentionally.
13
- * Please try not to mess with the Rakefile, version, or history. If you want to have your own version, or is otherwise necessary, that is fine, but please isolate to its own commit so I can cherry-pick around it.
14
-
15
- == Copyright
16
-
17
- Copyright (c) 2011 Ramon Tayag. See LICENSE.txt for
18
- further details.
19
-