mongoid_listable 0.0.3 → 0.0.4
Sign up to get free protection for your applications and to get access to all the features.
- data/README.md +57 -11
- data/lib/mongoid/lists.rb +18 -6
- data/mongoid_listable.gemspec +1 -1
- metadata +1 -1
data/README.md
CHANGED
@@ -1,39 +1,85 @@
|
|
1
1
|
# Mongoid Listable
|
2
2
|
|
3
3
|
Mongoid Listable will eventually be a full replacement library for Mongoid List or Mongoid Orderable. Both
|
4
|
-
libraries fail to accomplish the simple task this library handles:
|
5
|
-
relation.
|
4
|
+
libraries fail to accomplish the simple task this library handles: separate position scopes for each
|
5
|
+
defined `has_many` / `belongs_to` relation.
|
6
6
|
|
7
|
-
## Usage
|
7
|
+
## Basic Usage
|
8
8
|
|
9
9
|
class User
|
10
10
|
include Mongoid::Document
|
11
11
|
include Mongoid:Lists
|
12
12
|
|
13
13
|
has_many :photos
|
14
|
-
|
15
14
|
lists :photos
|
16
|
-
|
15
|
+
...
|
17
16
|
end
|
18
17
|
|
19
18
|
class Photo
|
20
19
|
include Mongoid::Document
|
21
20
|
|
22
21
|
belongs_to :user
|
23
|
-
|
22
|
+
...
|
24
23
|
end
|
25
24
|
|
26
|
-
|
25
|
+
In this example photos that are assigned to a user via by the method `user.photo_ids=[ids]` will maintain position based on the index
|
27
26
|
of the id in the array argument.
|
28
27
|
|
29
|
-
|
30
|
-
|
28
|
+
Each photo that belongs to the user will automatically obtain a field called `user_position`. The position field
|
29
|
+
is derived from the foreign key of the relation, replacing "_id" with "_position".
|
31
30
|
|
32
|
-
|
31
|
+
The 1-n relation of a user to their photos will automatically be ordered by `user_position` unless otherwise specified
|
32
|
+
via the standard `order` option to the `has_many` macro.
|
33
|
+
|
34
|
+
## Complex Relations
|
35
|
+
|
36
|
+
# Handles multiple has_many relations on same model!
|
37
|
+
|
38
|
+
class User
|
39
|
+
include Mongoid::Document
|
40
|
+
include Mongoid:Lists
|
41
|
+
|
42
|
+
has_many :featured_photos,
|
43
|
+
class_name: 'Photo',
|
44
|
+
inverse_of: :featured_by_user,
|
45
|
+
foreign_key: :featured_by_user_id
|
46
|
+
|
47
|
+
has_many :kodak_moments,
|
48
|
+
class_name: 'Photo',
|
49
|
+
inverse_of: :kodaked_by_user,
|
50
|
+
foreign_key: :kodaked_by_user_id
|
51
|
+
|
52
|
+
lists :featured_photos
|
53
|
+
lists :kodak_moments
|
54
|
+
...
|
55
|
+
end
|
56
|
+
|
57
|
+
class Photo
|
58
|
+
include Mongoid::Document
|
59
|
+
|
60
|
+
belongs_to :featured_by_user,
|
61
|
+
class_name: 'User',
|
62
|
+
inverse_of: featured_photos,
|
63
|
+
foreign_key: :featured_by_user_id
|
64
|
+
|
65
|
+
belongs_to :kodaked_by_user,
|
66
|
+
class_name: 'User',
|
67
|
+
inverse_of: kodak_moments,
|
68
|
+
foreign_key: :kodaked_by_user_id
|
69
|
+
...
|
70
|
+
end
|
71
|
+
|
72
|
+
|
73
|
+
In this example, there are two `has_many` relations defined between a user and photos. Each photo belonging to a user will
|
74
|
+
obtain two position fields: `featured_by_user_position` and `kodaked_by_user_position`.
|
75
|
+
|
76
|
+
You can optionally override the name of the position column:
|
33
77
|
|
34
78
|
lists :photos, column: :users_photos_order
|
35
79
|
|
36
|
-
|
80
|
+
## Todo
|
81
|
+
|
82
|
+
There's a lot more to add to the library! At this point, it conveniently handles standard rails-based multiselect form fields.
|
37
83
|
|
38
84
|
## Installation
|
39
85
|
|
data/lib/mongoid/lists.rb
CHANGED
@@ -11,19 +11,22 @@ module Mongoid
|
|
11
11
|
# Macro to set relation on which to make a list
|
12
12
|
#
|
13
13
|
# @param [ Symbol ] relation The name of the has_many relation
|
14
|
-
# @param [ Hash ]
|
14
|
+
# @param [ Hash ] options The options hash
|
15
15
|
#
|
16
16
|
# @return [ Mongoid:Relations:Metadata ] Instance of metadata for the relation
|
17
17
|
#
|
18
18
|
# @since 0.0.1
|
19
|
-
def lists
|
20
|
-
meta = reflect_on_association
|
19
|
+
def lists name, options={}
|
20
|
+
meta = reflect_on_association name
|
21
21
|
field_name = options[:column] ||
|
22
22
|
(meta.foreign_key.to_s.gsub(/_?id$/, '_position')).to_sym
|
23
23
|
|
24
24
|
|
25
|
-
# Override
|
26
|
-
|
25
|
+
# Override the default ids setter, first setting the correct position
|
26
|
+
# on each relation based on the index of its id in the given array.
|
27
|
+
#
|
28
|
+
# @override model#{name}_ids=
|
29
|
+
before_method self, "#{name.to_s.singularize}_ids=" do |ids|
|
27
30
|
ids.each_with_index do |id, index|
|
28
31
|
meta.klass.find(id).update_attribute field_name, index + 1
|
29
32
|
end
|
@@ -33,11 +36,20 @@ module Mongoid
|
|
33
36
|
end
|
34
37
|
end
|
35
38
|
|
36
|
-
meta[:order]
|
39
|
+
meta[:order] ||= "#{field_name} asc"
|
37
40
|
end
|
38
41
|
|
39
42
|
private
|
40
43
|
|
44
|
+
# Redefines a method on owner to first execute &block, then
|
45
|
+
# continue executing original method.
|
46
|
+
#
|
47
|
+
# @param [ Object ] owner The owner of the method
|
48
|
+
# @param [ String ] method The name of the method to override
|
49
|
+
# @param [ Proc ] &block The block to execute before original method
|
50
|
+
#
|
51
|
+
# @private
|
52
|
+
# @since 0.0.3
|
41
53
|
def before_method owner, method, &block
|
42
54
|
original_method = instance_method method
|
43
55
|
owner.re_define_method method do |*args|
|
data/mongoid_listable.gemspec
CHANGED
@@ -4,7 +4,7 @@ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
|
4
4
|
|
5
5
|
Gem::Specification.new do |spec|
|
6
6
|
spec.name = 'mongoid_listable'
|
7
|
-
spec.version = '0.0.
|
7
|
+
spec.version = '0.0.4'
|
8
8
|
spec.authors = [ 'richardcalahan' ]
|
9
9
|
spec.email = [ 'richard@calahan.me' ]
|
10
10
|
spec.description = ''
|