has 1.0.1 → 1.0.2
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/lib/has/has.rb +87 -0
- metadata +2 -1
data/lib/has/has.rb
ADDED
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
class << ActiveRecord::Base
|
|
2
|
+
|
|
3
|
+
def has(*xs)
|
|
4
|
+
opt = xs.extract_options!
|
|
5
|
+
name = xs.pop if xs.last.kind_of?(Symbol)
|
|
6
|
+
|
|
7
|
+
argument_name_for = { Range => :range, Fixnum => :count }
|
|
8
|
+
while x = xs.shift
|
|
9
|
+
opt[argument_name_for[x.class]] = x
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
if key = (opt.keys & [ :attributed, :nested ]).first
|
|
13
|
+
send "has_#{key}", opt.delete(key), opt
|
|
14
|
+
else
|
|
15
|
+
has_associated name, opt
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def has_attributed(name, opt = {})
|
|
20
|
+
opt[:include] = true if opt[:include].nil?
|
|
21
|
+
opt[:conditions] ||= {}
|
|
22
|
+
opt[:conditions][:attribute_name] = name.to_s
|
|
23
|
+
opt[:orderable] = :attribute_ordinal if opt[:orderable] == true
|
|
24
|
+
opt[:as] = :attributable
|
|
25
|
+
|
|
26
|
+
has_nested name, opt
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def has_nested(name, opt = {})
|
|
30
|
+
opt[:dependent] = :destroy if opt[:dependent].nil?
|
|
31
|
+
allow_destroy = opt[:dependent] == :destroy
|
|
32
|
+
default_include = opt.delete(:include) == true
|
|
33
|
+
if orderable = opt.delete(:orderable)
|
|
34
|
+
opt[:order] = orderable
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
has_associated name, opt
|
|
38
|
+
|
|
39
|
+
accepts_nested_attributes_for name, allow_destroy: allow_destroy
|
|
40
|
+
default_scope includes(name) if default_include
|
|
41
|
+
|
|
42
|
+
if orderable
|
|
43
|
+
setter = instance_method setter_name = "#{name}_attributes="
|
|
44
|
+
|
|
45
|
+
define_method setter_name do |attr|
|
|
46
|
+
attr = attr.values if attr.is_a? Hash
|
|
47
|
+
attr.each_with_index{ |e, i| e[orderable] = i }
|
|
48
|
+
setter.bind(self).call attr
|
|
49
|
+
send(name).sort_by! &orderable
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
before_save do
|
|
53
|
+
send(name).each_with_index{ |e, i| e[orderable] = i }
|
|
54
|
+
end
|
|
55
|
+
end
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
def has_associated(name, opt = {})
|
|
59
|
+
range = opt.delete :range
|
|
60
|
+
count = opt.delete :count
|
|
61
|
+
inf = 1.0/0
|
|
62
|
+
min = opt.keys.find{ |k| Integer === k }
|
|
63
|
+
max = opt.delete min if min
|
|
64
|
+
max = inf if max == :many
|
|
65
|
+
|
|
66
|
+
range ||= if count then count .. count
|
|
67
|
+
elsif min && max then min .. max
|
|
68
|
+
else
|
|
69
|
+
name_s = name.to_s
|
|
70
|
+
is_plural = name_s.pluralize == name_s
|
|
71
|
+
is_singular = name_s.singularize == name_s
|
|
72
|
+
|
|
73
|
+
raise ArgumentError.new "`has` can't determine whether \"#{name_s}\" is plural or singular. Please supply a count or range, or define an inflection." if is_plural == is_singular
|
|
74
|
+
|
|
75
|
+
0 .. (is_plural ? inf : 1)
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
if range.end == 1 then has_one name, opt
|
|
79
|
+
else
|
|
80
|
+
opt[:limit] = range.end unless range.end == inf
|
|
81
|
+
has_many name, opt
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
validates_presence_of name if range.begin > 0
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
end
|
metadata
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
name: has
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
4
|
prerelease:
|
|
5
|
-
version: 1.0.
|
|
5
|
+
version: 1.0.2
|
|
6
6
|
platform: ruby
|
|
7
7
|
authors:
|
|
8
8
|
- Alex Goldsmith
|
|
@@ -34,6 +34,7 @@ extensions: []
|
|
|
34
34
|
extra_rdoc_files: []
|
|
35
35
|
|
|
36
36
|
files:
|
|
37
|
+
- lib/has/has.rb
|
|
37
38
|
- lib/has.rb
|
|
38
39
|
- Rakefile
|
|
39
40
|
- README.rdoc
|