og 0.31.0 → 0.40.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/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>
|