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.
Files changed (2) hide show
  1. data/lib/has/has.rb +87 -0
  2. 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.1
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