mongoid_listable 0.0.3 → 0.0.4
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/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 = ''
|