og 0.31.0 → 0.40.0
Sign up to get free protection for your applications and to get access to all the features.
- data/doc/{AUTHORS → CONTRIBUTORS} +26 -10
- data/doc/LICENSE +2 -3
- data/doc/RELEASES +56 -7
- data/doc/tutorial.txt +15 -15
- data/lib/glue/cacheable.rb +2 -5
- data/lib/glue/hierarchical.rb +1 -4
- data/lib/glue/optimistic_locking.rb +0 -2
- data/lib/glue/orderable.rb +79 -75
- data/lib/glue/revisable.rb +19 -24
- data/lib/glue/searchable.rb +0 -2
- data/lib/glue/taggable.rb +31 -29
- data/lib/glue/timestamped.rb +4 -2
- data/lib/og.rb +50 -29
- data/lib/og/adapter.rb +19 -0
- data/lib/og/adapter/mysql.rb +212 -0
- data/lib/og/adapter/mysql/override.rb +34 -0
- data/lib/og/adapter/mysql/script.rb +15 -0
- data/lib/og/adapter/mysql/utils.rb +40 -0
- data/lib/og/adapter/postgresql.rb +231 -0
- data/lib/og/adapter/postgresql/override.rb +117 -0
- data/lib/og/adapter/postgresql/script.rb +15 -0
- data/lib/og/adapter/postgresql/utils.rb +35 -0
- data/lib/og/adapter/sqlite.rb +132 -0
- data/lib/og/adapter/sqlite/override.rb +33 -0
- data/lib/og/adapter/sqlite/script.rb +15 -0
- data/lib/og/collection.rb +35 -7
- data/lib/og/{evolution.rb → dump.rb} +4 -5
- data/lib/og/entity.rb +102 -173
- data/lib/og/entity/clone.rb +119 -0
- data/lib/og/errors.rb +0 -2
- data/lib/og/manager.rb +85 -37
- data/lib/og/relation.rb +52 -34
- data/lib/og/relation/belongs_to.rb +0 -2
- data/lib/og/relation/has_many.rb +27 -4
- data/lib/og/relation/joins_many.rb +41 -14
- data/lib/og/relation/many_to_many.rb +10 -0
- data/lib/og/relation/refers_to.rb +22 -5
- data/lib/og/store.rb +80 -86
- data/lib/og/store/sql.rb +710 -713
- data/lib/og/store/sql/evolution.rb +119 -0
- data/lib/og/store/sql/join.rb +155 -0
- data/lib/og/store/sql/utils.rb +149 -0
- data/lib/og/test/assertions.rb +1 -3
- data/lib/og/test/testcase.rb +0 -2
- data/lib/og/types.rb +2 -5
- data/lib/og/validation.rb +6 -9
- data/test/{og/mixin → glue}/tc_hierarchical.rb +3 -13
- data/test/glue/tc_og_paginate.rb +47 -0
- data/test/{og/mixin → glue}/tc_optimistic_locking.rb +2 -12
- data/test/{og/mixin → glue}/tc_orderable.rb +15 -23
- data/test/glue/tc_orderable2.rb +47 -0
- data/test/glue/tc_revisable.rb +3 -3
- data/test/{og/mixin → glue}/tc_taggable.rb +20 -10
- data/test/{og/mixin → glue}/tc_timestamped.rb +2 -12
- data/test/glue/tc_webfile.rb +36 -0
- data/test/og/CONFIG.rb +8 -11
- data/test/og/multi_validations_model.rb +14 -0
- data/test/og/store/tc_filesys.rb +3 -1
- data/test/og/store/tc_kirby.rb +16 -13
- data/test/og/store/tc_sti.rb +11 -11
- data/test/og/store/tc_sti2.rb +79 -0
- data/test/og/tc_build.rb +41 -0
- data/test/og/tc_cacheable.rb +3 -2
- data/test/og/tc_has_many.rb +96 -0
- data/test/og/tc_inheritance.rb +6 -4
- data/test/og/tc_joins_many.rb +93 -0
- data/test/og/tc_multi_validations.rb +5 -7
- data/test/og/tc_multiple.rb +7 -6
- data/test/og/tc_override.rb +13 -7
- data/test/og/tc_primary_key.rb +30 -0
- data/test/og/tc_relation.rb +8 -14
- data/test/og/tc_reldelete.rb +163 -0
- data/test/og/tc_reverse.rb +17 -14
- data/test/og/tc_scoped.rb +3 -11
- data/test/og/tc_setup.rb +13 -11
- data/test/og/tc_store.rb +21 -28
- data/test/og/tc_validation2.rb +2 -2
- data/test/og/tc_validation_loop.rb +17 -15
- metadata +109 -103
- data/INSTALL +0 -91
- data/ProjectInfo +0 -51
- data/README +0 -177
- data/doc/config.txt +0 -28
- data/examples/README +0 -23
- data/examples/mysql_to_psql.rb +0 -71
- data/examples/run.rb +0 -271
- data/lib/glue/tree.rb +0 -218
- data/lib/og/store/alpha/filesys.rb +0 -110
- data/lib/og/store/alpha/memory.rb +0 -295
- data/lib/og/store/alpha/sqlserver.rb +0 -256
- data/lib/og/store/kirby.rb +0 -490
- data/lib/og/store/mysql.rb +0 -415
- data/lib/og/store/psql.rb +0 -875
- data/lib/og/store/sqlite.rb +0 -348
- data/lib/og/store/sqlite2.rb +0 -241
- data/setup.rb +0 -1585
- data/test/og/tc_sti_find.rb +0 -35
@@ -1,46 +1,62 @@
|
|
1
1
|
MAIN DEVELOPER:
|
2
2
|
|
3
|
-
* George Moschovitis <
|
3
|
+
* George Moschovitis <george.moschovitis@gmail.com>
|
4
4
|
Project leader, architecture and design, main coder,
|
5
5
|
documentation, maintainer.
|
6
6
|
|
7
7
|
IDEAS, ADDITIONAL CODING, SUPPORT:
|
8
8
|
|
9
|
-
*
|
10
|
-
|
9
|
+
* Jonathan Buch <jonathan.buch@gmail.com>
|
10
|
+
Patches.
|
11
|
+
|
12
|
+
* Fabian Buch <fabian@fabian-buch.de>
|
13
|
+
Patches.
|
11
14
|
|
15
|
+
* Michael Fellinger <m.fellinger@gmail.com>
|
16
|
+
Patches, bug fixes.
|
17
|
+
|
18
|
+
* Rob Pitt <rob@motionpath.co.uk>
|
19
|
+
Patches, Bug fixes.
|
20
|
+
|
12
21
|
* Ysabel <deb@ysabel.org>
|
13
22
|
Refactoring, patches.
|
14
23
|
|
15
24
|
* Thomas Sawyer <transfire@gmail.com>
|
16
|
-
Refactoring, code cleanup.
|
25
|
+
Refactoring, patches, code cleanup.
|
17
26
|
|
18
27
|
* Guillaume Pierronnet <guillaume.pierronnet@laposte.net>
|
19
28
|
Tons of patches.
|
20
29
|
|
30
|
+
* Michael Neumann <mneumann@ntecs.de>
|
31
|
+
Design, additional coding and bug reports.
|
32
|
+
|
21
33
|
* Aleksi Niemela <Aleksi.Niemela@cs.helsinki.fi>
|
22
34
|
Bug reports and patches.
|
23
35
|
|
24
|
-
* Anastasios Koutoumanos <ak@navel.gr>
|
25
|
-
Design, additional coding.
|
26
|
-
|
27
36
|
* Julien Perrot <jperrot@exosec.fr>
|
28
37
|
Bug reports and patches.
|
29
38
|
|
30
39
|
* Ghislain Mary <gmary@lunacymaze.org>
|
31
40
|
Bug reports and patches (sqlite3 driver).
|
32
41
|
|
33
|
-
*
|
34
|
-
|
42
|
+
* Dirk Barnikel <dirk.barnikel@gmx.de>
|
43
|
+
Initial Revisable code.
|
35
44
|
|
36
45
|
* Dylan Bruzenak <dylanb@digitalvalence.com>
|
37
46
|
Patches (kirby).
|
38
47
|
|
39
48
|
* Matt Bowen <matt.bowen@farweststeel.com>
|
40
|
-
Oracle driver, documentation.
|
49
|
+
Old Oracle driver, documentation.
|
41
50
|
|
42
51
|
* Aidan Rogers <aidan@infurious.com>
|
43
52
|
Bug reports, patches.
|
53
|
+
|
54
|
+
* Darrick W <darrick@innatesoftware.com>
|
55
|
+
Patches.
|
56
|
+
|
57
|
+
* Anastasios Koutoumanos <ak@navel.gr>
|
58
|
+
Design, additional coding.
|
44
59
|
|
45
60
|
* Thomas Quas <tquas@yahoo.com>
|
46
61
|
Ideas, bug reports, unit tests.
|
62
|
+
|
data/doc/LICENSE
CHANGED
@@ -1,7 +1,6 @@
|
|
1
1
|
The BSD License
|
2
2
|
|
3
|
-
Copyright (c) 2004-
|
4
|
-
Copyright (c) 2004-2005, Navel Ltd. (http://www.navel.gr)
|
3
|
+
Copyright (c) 2004-2006, George K. Moschovitis. (http://www.gmosx.com)
|
5
4
|
All rights reserved.
|
6
5
|
|
7
6
|
Redistribution and use in source and binary forms, with or without
|
@@ -15,7 +14,7 @@ notice, this list of conditions and the following disclaimer.
|
|
15
14
|
notice, this list of conditions and the following disclaimer in the
|
16
15
|
documentation and/or other materials provided with the distribution.
|
17
16
|
|
18
|
-
* Neither the name of
|
17
|
+
* Neither the name of Og nor the names of its contributors may be
|
19
18
|
used to endorse or promote products derived from this software
|
20
19
|
without specific prior written permission.
|
21
20
|
|
data/doc/RELEASES
CHANGED
@@ -1,12 +1,61 @@
|
|
1
|
-
== Version 0.
|
1
|
+
== Version 0.40.0
|
2
2
|
|
3
|
-
|
3
|
+
This is the biggest release yet! Tons of new wonderful features,
|
4
|
+
code refactoring, bug fixes, documentation improvements and so
|
5
|
+
much more.
|
4
6
|
|
5
|
-
|
7
|
+
Special thanks for this release fly to Jonas Pfeniger,
|
8
|
+
Jonathan/Fabian Buch and Michael Fellinger.
|
6
9
|
|
7
|
-
|
10
|
+
Most notable changes:
|
11
|
+
|
12
|
+
* Fully transparent Og managed objects. No need to use the
|
13
|
+
special property notation. Just use the standard attr_accessor
|
14
|
+
macro:
|
15
|
+
|
16
|
+
class User
|
17
|
+
attr_accessor :name, String, :sql => 'VARCHAR(32)
|
18
|
+
attr_accessor :password, String
|
19
|
+
attr_accessor :age, :login_count, Fixnum
|
20
|
+
|
21
|
+
belongs_to :group
|
22
|
+
has_many :comments
|
23
|
+
joins_many :categories
|
24
|
+
end
|
25
|
+
|
26
|
+
Og automatically detects and manages this class!
|
27
|
+
|
28
|
+
* The Og adapter model was re-engineered from scratch. The new
|
29
|
+
adapter code is better refactored. It is now extremely easy to
|
30
|
+
write new adapters for various RDBMS systems.
|
31
|
+
|
32
|
+
* Og build mode. This avoids multiple sql queries when you are
|
33
|
+
'building' (ie attaching related objects) a new object.
|
34
|
+
|
35
|
+
* You can now easily lookup Og entities by name:
|
36
|
+
|
37
|
+
u = User[1] # classic
|
38
|
+
|
39
|
+
or
|
40
|
+
|
41
|
+
u = User['gmosx'] # this works as well!
|
42
|
+
|
43
|
+
for the new method to work you need to annotate the attribute
|
44
|
+
to use for named lookups:
|
45
|
+
|
46
|
+
class User
|
47
|
+
attr_accessor :name, String, :key => true
|
48
|
+
..
|
49
|
+
end
|
50
|
+
|
51
|
+
* Og set attribute, a nice helper to set only some attributes.
|
52
|
+
|
53
|
+
b = Book[1]
|
54
|
+
b.set_attribute :title => 'Hello' # updates only title in the DB
|
55
|
+
b.instance_attribute_set '@title', 'Hello' # Ruby style
|
56
|
+
b.set_attributes :title => '1', :hits => 3
|
8
57
|
|
9
|
-
*
|
58
|
+
* Many more bug fixes and smaller improvements.
|
10
59
|
|
11
60
|
== Version 0.30.0
|
12
61
|
|
@@ -490,10 +539,10 @@ tagging to your appplication.
|
|
490
539
|
..
|
491
540
|
end
|
492
541
|
|
493
|
-
article.tag('
|
542
|
+
article.tag('great', 'gmosx', 'nitro')
|
494
543
|
article.tags
|
495
544
|
article.tag_names
|
496
|
-
Article.find_with_tags('
|
545
|
+
Article.find_with_tags('great', 'gmosx')
|
497
546
|
Article.find_with_any_tag('name', 'gmosx')
|
498
547
|
|
499
548
|
t = Article::Tag.find_by_name('ruby')
|
data/doc/tutorial.txt
CHANGED
@@ -91,7 +91,7 @@ attribute that contains metadata is called a property. For
|
|
91
91
|
each attr* method, there is a corresponding prop* method. That is,
|
92
92
|
|
93
93
|
attr => prop
|
94
|
-
attr_accessor =>
|
94
|
+
attr_accessor => attr_accessor
|
95
95
|
attr_reader => prop_reader
|
96
96
|
attr_writer => prop_writer
|
97
97
|
|
@@ -100,25 +100,25 @@ Here are the class definitions using the property mechanism:
|
|
100
100
|
require 'og'
|
101
101
|
|
102
102
|
class Category
|
103
|
-
|
103
|
+
attr_accessor :name, String
|
104
104
|
end
|
105
105
|
|
106
106
|
class Post
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
107
|
+
attr_accessor :title, String
|
108
|
+
attr_accessor :body, String
|
109
|
+
attr_accessor :author, String
|
110
|
+
attr_accessor :create_time, Time
|
111
|
+
attr_accessor :hits, Fixnum
|
112
112
|
end
|
113
113
|
|
114
114
|
class Comment
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
115
|
+
attr_accessor :title, String
|
116
|
+
attr_accessor :body, String
|
117
|
+
attr_accessor :author, String
|
118
|
+
attr_accessor :create_time, Time
|
119
119
|
end
|
120
120
|
|
121
|
-
Notice that the
|
121
|
+
Notice that the attr_accessor works similar to Ruby's attr_accessor.
|
122
122
|
Here are some examples:
|
123
123
|
|
124
124
|
prop :title, true, String
|
@@ -154,7 +154,7 @@ db = Og::Database.new(
|
|
154
154
|
:database => 'test',
|
155
155
|
:adapter => 'psql',
|
156
156
|
:user => 'postgres',
|
157
|
-
:password => '
|
157
|
+
:password => 'gmrulez'
|
158
158
|
)
|
159
159
|
|
160
160
|
Now you are ready to save your first object into Postgres. Add the following code:
|
@@ -574,7 +574,7 @@ db = Og::Database.new(
|
|
574
574
|
:database => 'test',
|
575
575
|
:adapter => 'mysql',
|
576
576
|
:user => 'postgres',
|
577
|
-
:password => '
|
577
|
+
:password => 'gmrulez'
|
578
578
|
)
|
579
579
|
|
580
580
|
A new MySQL database is automatically created along with all tables, indices, etc. You get all
|
@@ -587,7 +587,7 @@ You betcha! You can to find more about Og by reading the available RDoc document
|
|
587
587
|
|
588
588
|
For any questions regarding Og, feel free to ask on the ruby-talk
|
589
589
|
mailing list (which is mirrored to comp.lang.ruby) or contact
|
590
|
-
mailto:
|
590
|
+
mailto:george.moschovitis@gmail.com.
|
591
591
|
|
592
592
|
A Nitro specific mailing list is also available. You can post questions about
|
593
593
|
Og to this list. Please subscribe to nitro-general@rubyforge.com. The homepage
|
data/lib/glue/cacheable.rb
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
require '
|
1
|
+
require 'facet/classmethods'
|
2
2
|
|
3
3
|
module Glue
|
4
4
|
|
@@ -7,7 +7,6 @@ module Glue
|
|
7
7
|
#
|
8
8
|
# If you use a distributed cache (drb, memcache, etc) , you may
|
9
9
|
# have to start a separate server.
|
10
|
-
#
|
11
10
|
#--
|
12
11
|
# gmosx, WARNING: If the file lib/og/entity.rb is changed
|
13
12
|
# this file should be updated to reflect the changes!
|
@@ -15,7 +14,7 @@ module Glue
|
|
15
14
|
|
16
15
|
module Cacheable
|
17
16
|
|
18
|
-
|
17
|
+
class_methods do
|
19
18
|
|
20
19
|
def after_enchant(base)
|
21
20
|
base.module_eval do
|
@@ -150,5 +149,3 @@ module Cacheable
|
|
150
149
|
end
|
151
150
|
|
152
151
|
end
|
153
|
-
|
154
|
-
# * George Moschovitis <gm@navel.gr>
|
data/lib/glue/hierarchical.rb
CHANGED
@@ -11,7 +11,7 @@ module Glue
|
|
11
11
|
|
12
12
|
module NestedSets
|
13
13
|
|
14
|
-
def self.included_with_parameters
|
14
|
+
def self.included_with_parameters base, options
|
15
15
|
c = {
|
16
16
|
:left => 'lft',
|
17
17
|
:right => 'rgt',
|
@@ -140,6 +140,3 @@ module Hierarchical
|
|
140
140
|
end
|
141
141
|
|
142
142
|
end
|
143
|
-
|
144
|
-
# * George Moschovitis <gm@navel.gr>
|
145
|
-
# * Aleksi Niemela <Aleksi.Niemela@cs.helsinki.fi>
|
data/lib/glue/orderable.rb
CHANGED
@@ -4,72 +4,79 @@ require 'facets/more/aspects'
|
|
4
4
|
module Glue
|
5
5
|
|
6
6
|
# Attach list/ordering methods to the enchanted class.
|
7
|
+
#
|
8
|
+
# === Comments
|
9
|
+
#
|
10
|
+
# If you use the scope option, you have to set he parent (scope)
|
11
|
+
# of the object before inserting to have correct ordering.
|
7
12
|
|
8
13
|
module Orderable
|
9
|
-
include
|
14
|
+
include Aspects
|
10
15
|
|
11
16
|
def self.included_with_parameters(base, opt)
|
12
|
-
base.module_eval do
|
13
17
|
|
14
|
-
|
18
|
+
# The attribute to use to keep the position.
|
19
|
+
|
20
|
+
opt_position = opt.fetch(:position, 'position')
|
15
21
|
|
16
|
-
|
22
|
+
# The type of the position attribute.
|
23
|
+
|
24
|
+
opt_type = opt.fetch(:type, Fixnum)
|
17
25
|
|
18
|
-
|
19
|
-
|
20
|
-
|
26
|
+
# A user defined condition.
|
27
|
+
|
28
|
+
opt_condition = opt[:condition]
|
21
29
|
|
22
|
-
|
23
|
-
|
24
|
-
|
30
|
+
# A condition based on a key field (?)
|
31
|
+
|
32
|
+
opt_scope = opt[:scope]
|
25
33
|
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
end
|
34
|
+
# clean scope field.
|
35
|
+
|
36
|
+
if opt_scope
|
37
|
+
if opt_scope.to_s !~ /_oid$/
|
38
|
+
opt_scope = "#{opt_scope}_oid".to_sym
|
39
|
+
else
|
40
|
+
opt_scope = opt_scope.to_sym
|
34
41
|
end
|
42
|
+
end
|
43
|
+
|
44
|
+
base.module_eval %{
|
45
|
+
attr_accessor :#{opt_position}, #{opt_type}
|
35
46
|
|
36
|
-
|
37
|
-
opt_position
|
47
|
+
def orderable_attribute
|
48
|
+
#{opt_position.inspect}
|
49
|
+
end
|
50
|
+
|
51
|
+
def orderable_position
|
52
|
+
@#{opt_position}
|
38
53
|
end
|
39
54
|
|
40
|
-
|
41
|
-
|
55
|
+
def orderable_position= (pos)
|
56
|
+
@#{opt_position} = pos
|
42
57
|
end
|
43
58
|
|
44
|
-
|
45
|
-
|
59
|
+
def orderable_type
|
60
|
+
#{opt_type}
|
61
|
+
end
|
62
|
+
|
63
|
+
def orderable_scope
|
64
|
+
#{opt_scope.inspect}
|
46
65
|
end
|
47
66
|
|
48
|
-
|
67
|
+
def orderable_condition
|
49
68
|
scope = orderable_scope
|
50
69
|
if scope
|
51
70
|
scope_value = send(scope)
|
52
|
-
scope = scope_value ? "
|
71
|
+
scope = scope_value ? "\#{scope} = \#{scope_value}" : "\#{scope} IS NULL"
|
53
72
|
end
|
54
|
-
return [ opt_condition, scope ].compact
|
73
|
+
return [ #{opt_condition.inspect}, scope ].compact
|
55
74
|
end
|
75
|
+
}
|
56
76
|
|
57
|
-
|
58
|
-
|
59
|
-
unless method_defined?( opt_position )
|
60
|
-
define_method( opt_position ) do @position ; end
|
61
|
-
define_method( "#{opt_position}=" ) do |x| @position = x ; end
|
62
|
-
property opt_position, opt_type
|
63
|
-
end
|
77
|
+
end
|
64
78
|
|
65
|
-
|
66
|
-
|
67
|
-
attr_accessor :position
|
68
|
-
|
69
|
-
end
|
70
|
-
end #dynamic_feature
|
71
|
-
|
72
|
-
before "add_to_bottom", :on => [:og_insert, :og_update]
|
79
|
+
before "add_to_bottom", :on => :og_insert
|
73
80
|
before "decrement_position_of_lower_items", :on => :og_delete
|
74
81
|
|
75
82
|
# Move higher.
|
@@ -82,7 +89,7 @@ module Orderable
|
|
82
89
|
end
|
83
90
|
end
|
84
91
|
end
|
85
|
-
|
92
|
+
|
86
93
|
# Move lower.
|
87
94
|
|
88
95
|
def move_lower
|
@@ -115,22 +122,22 @@ module Orderable
|
|
115
122
|
# Move to a specific position.
|
116
123
|
|
117
124
|
def move_to(dest_position)
|
118
|
-
return if
|
125
|
+
return if self.orderable_position == dest_position
|
119
126
|
|
120
|
-
pos =
|
127
|
+
pos = orderable_attribute
|
121
128
|
con = orderable_condition
|
122
129
|
|
123
130
|
self.class.transaction do
|
124
|
-
if
|
131
|
+
if orderable_position < dest_position
|
125
132
|
adj = "#{pos} = #{pos} - 1"
|
126
|
-
con = con + [ "#{pos} > #{
|
133
|
+
con = con + [ "#{pos} > #{orderable_position}", "#{pos} <= #{dest_position}" ]
|
127
134
|
else
|
128
135
|
adj = "#{pos} = #{pos} + 1"
|
129
|
-
con = con + [ "#{pos} < #{
|
136
|
+
con = con + [ "#{pos} < #{orderable_position}", "#{pos} >= #{dest_position}" ]
|
130
137
|
end
|
131
138
|
self.class.update( adj, :condition => con.join(' AND ') )
|
132
|
-
|
133
|
-
|
139
|
+
self.orderable_position = dest_position
|
140
|
+
update_attribute(orderable_attribute)
|
134
141
|
end
|
135
142
|
|
136
143
|
self
|
@@ -141,7 +148,7 @@ module Orderable
|
|
141
148
|
end
|
142
149
|
|
143
150
|
def add_to_bottom
|
144
|
-
|
151
|
+
self.orderable_position = bottom_position + 1
|
145
152
|
end
|
146
153
|
|
147
154
|
def add_to
|
@@ -149,15 +156,15 @@ module Orderable
|
|
149
156
|
end
|
150
157
|
|
151
158
|
def higher_item
|
152
|
-
pos =
|
153
|
-
con = orderable_condition + [ "#{pos} = #{
|
159
|
+
pos = orderable_attribute
|
160
|
+
con = orderable_condition + [ "#{pos} = #{orderable_position - 1}" ]
|
154
161
|
self.class.one( :condition => con.join(' AND ') )
|
155
162
|
end
|
156
163
|
alias_method :previous_item, :higher_item
|
157
164
|
|
158
165
|
def lower_item
|
159
|
-
pos =
|
160
|
-
con = orderable_condition + [ "#{pos} = #{
|
166
|
+
pos = orderable_attribute
|
167
|
+
con = orderable_condition + [ "#{pos} = #{orderable_position + 1}" ]
|
161
168
|
self.class.one( :condition => con.join(' AND ') )
|
162
169
|
end
|
163
170
|
alias_method :next_item, :lower_item
|
@@ -168,7 +175,7 @@ module Orderable
|
|
168
175
|
alias_method :first_item, :top_item
|
169
176
|
|
170
177
|
def bottom_item
|
171
|
-
pos =
|
178
|
+
pos = orderable_attribute
|
172
179
|
con = orderable_condition
|
173
180
|
con = con.empty? ? nil : con.join(' AND ')
|
174
181
|
self.class.one(:condition => con, :order => "#{pos} DESC", :limit => 1)
|
@@ -176,62 +183,59 @@ module Orderable
|
|
176
183
|
alias_method :last_item, :last_item
|
177
184
|
|
178
185
|
def top?
|
179
|
-
|
186
|
+
self.orderable_position == 1
|
180
187
|
end
|
181
188
|
alias_method :first?, :top?
|
182
189
|
|
183
190
|
def bottom?
|
184
|
-
|
191
|
+
self.orderable_position == bottom_position
|
185
192
|
end
|
186
193
|
alias_method :last?, :bottom?
|
187
194
|
|
188
195
|
def increment_position
|
189
|
-
|
190
|
-
|
196
|
+
self.orderable_position += 1
|
197
|
+
update_attribute(self.orderable_attribute)
|
191
198
|
end
|
192
199
|
|
193
200
|
def decrement_position
|
194
|
-
|
195
|
-
|
201
|
+
self.orderable_position -= 1
|
202
|
+
update_attribute(self.orderable_attribute)
|
196
203
|
end
|
197
204
|
|
198
205
|
def bottom_position
|
199
206
|
item = bottom_item
|
200
|
-
item ? item.
|
207
|
+
item ? (item.orderable_position || 0) : 0
|
201
208
|
end
|
202
209
|
|
203
210
|
def set_top_position
|
204
|
-
|
205
|
-
|
211
|
+
self.orderable_position = 1
|
212
|
+
update_attribute(orderable_attribute)
|
206
213
|
end
|
207
214
|
|
208
215
|
def set_bottom_position
|
209
|
-
|
210
|
-
|
216
|
+
self.orderable_position = bottom_position + 1
|
217
|
+
update_attribute(orderable_attribute)
|
211
218
|
end
|
212
219
|
|
213
220
|
def increment_position_of_higher_items
|
214
|
-
pos =
|
215
|
-
con = orderable_condition + [ "#{pos} < #{
|
221
|
+
pos = orderable_attribute
|
222
|
+
con = orderable_condition + [ "#{pos} < #{orderable_position}" ]
|
216
223
|
self.class.update "#{pos}=(#{pos} + 1)", :condition => con.join(' AND ')
|
217
224
|
end
|
218
225
|
|
219
226
|
def increment_position_of_all_items
|
220
|
-
pos =
|
227
|
+
pos = orderable_attribute
|
221
228
|
con = orderable_condition
|
222
229
|
con = con.empty? ? nil : con.join(' AND ')
|
223
230
|
self.class.update "#{pos}=(#{pos} + 1)", :condition => con
|
224
231
|
end
|
225
232
|
|
226
233
|
def decrement_position_of_lower_items
|
227
|
-
pos =
|
228
|
-
con = orderable_condition + [ "#{pos} > #{
|
234
|
+
pos = orderable_attribute
|
235
|
+
con = orderable_condition + [ "#{pos} > #{orderable_position}" ]
|
229
236
|
self.class.update "#{pos}=(#{pos} - 1)", :condition => con.join(' AND ')
|
230
237
|
end
|
231
238
|
|
232
239
|
end
|
233
240
|
|
234
241
|
end
|
235
|
-
|
236
|
-
# * George Moschovitis <gm@navel.gr>
|
237
|
-
# * Thomas Sawyer <transfire@gmail.com>
|