yaml_b_sides 0.4.3 → 0.5.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: fe6d60416f8f0b980e021475bc8bec4d22816232
4
- data.tar.gz: c0eb789a44fb284ed36afc977490fe2e097c6915
3
+ metadata.gz: f9c1e5106acd3094fc9410a28732fa9133834ba8
4
+ data.tar.gz: 2b3d6b50d7d4531c0e6d30f5539ba442fd607c8d
5
5
  SHA512:
6
- metadata.gz: 5966c40826854c511bc4a3108139de921bbf32f61e5bc26f474957103dc6b47fd36718e50198267c3b9bd1fa6b5c3a604b17bf62f26ceb29a321606f9c66f2e3
7
- data.tar.gz: 7d6101f9afc46dfc442ad78dc61ebe614a62770148b41777ebef9a35e5370e8ad82f37f2f2cf2c70528935dcb671ae67a90d8880649549f477a4e1eb2b7c6387
6
+ metadata.gz: 356d4ff801988430a58ccb281009b914b868edcd44f9f0a83d9ecb926c56973c89fe3827dbf6fc9c00655d38978a4e266798af7ac5a0bcc1d2b463b6a742b143
7
+ data.tar.gz: e11f162cf0e71a2f63142a584c7a534954986a28874b6a0b780a4cbb37282cfd2b4d67d44f7e9adea46e5b544a94f9a8046f8375e9bb6d1e5c6cd5c4b5604156
data/README.md CHANGED
@@ -98,7 +98,7 @@ Associations have some of the standard ActiveRecord options. Namely:
98
98
 
99
99
  * `through`: many to may association helper.
100
100
 
101
- ```ruby
101
+ ```ruby
102
102
  class Person < YamlBSides::Base
103
103
  has_many :person_foods
104
104
  has_many :favorite_foods, through: :person_foods, class_name: "Food"
@@ -115,6 +115,44 @@ Associations have some of the standard ActiveRecord options. Namely:
115
115
 
116
116
  __NOTE__: only works for `has_one` and `has_many`
117
117
 
118
+ * `as`: specifies what the associated object calls the caller
119
+ ```ruby
120
+ class Person
121
+ has_many :images, as: :target
122
+ end
123
+
124
+ class Image
125
+ belongs_to :target, class: Person
126
+ end
127
+ ```
128
+ __NOTE__: only works for `has_one` and `has_many`
129
+
130
+ * `polymorphic`: specifies a polymorphic `belongs_to` association. Better explanation [here, on the ActiveRecord page](http://guides.rubyonrails.org/association_basics.html#polymorphic-associations)
131
+ ```ruby
132
+ class Person
133
+ has_many :images, as: :target
134
+ end
135
+
136
+ class Party
137
+ has_many :images, as: :target
138
+ end
139
+
140
+ class Image
141
+ belongs_to :target, polymorphic: true
142
+ end
143
+ ```
144
+ And then the `images.yml` looks something like
145
+ ```yml
146
+ image-1:
147
+ thing_id: a
148
+ thing_class: Person
149
+ # ...
150
+ image-2:
151
+ thing_id: a
152
+ thing_class: PArty
153
+ #...
154
+ ```
155
+
118
156
  ### Example
119
157
 
120
158
  To use the `People` class from earlier, a fully fleshed out model would look something like:
@@ -11,7 +11,9 @@ module YamlBSides
11
11
  class << self
12
12
 
13
13
  def belongs_to( name, opts = {} )
14
- process Associations::BelongsTo.new( self, name, opts )
14
+ association = Associations::BelongsTo.new( self, name, opts )
15
+ process association
16
+ index association.key
15
17
  end
16
18
 
17
19
  def has_one( name, opts = {} )
@@ -38,7 +40,7 @@ module YamlBSides
38
40
  self._cached_associations ||= {}
39
41
 
40
42
  unless self._cached_associations.has_key? association.name
41
- result = association.klass.send( association.action, association.query( self ) )
43
+ result = association.klass( self ).send( association.action, association.query( self ) )
42
44
 
43
45
  self._cached_associations[association.name] = result
44
46
  end
@@ -2,8 +2,8 @@ module YamlBSides
2
2
  module Associations
3
3
  autoload :Base, 'yaml_b_sides/associations/base'
4
4
  autoload :BelongsTo, 'yaml_b_sides/associations/belongs_to'
5
+ autoload :Hasable, 'yaml_b_sides/associations/hasable'
5
6
  autoload :HasMany, 'yaml_b_sides/associations/has_many'
6
7
  autoload :HasOne, 'yaml_b_sides/associations/has_one'
7
- autoload :Through, 'yaml_b_sides/associations/through'
8
8
  end
9
9
  end
@@ -8,9 +8,11 @@ module YamlBSides
8
8
  self.name = name
9
9
  self.opts = opts
10
10
  self.key = idify base_class
11
+
12
+ sanitize_opts( base_class )
11
13
  end
12
14
 
13
- def klass
15
+ def klass( instance = nil )
14
16
  @klass ||= association_class name, opts
15
17
  end
16
18
 
@@ -30,6 +32,22 @@ module YamlBSides
30
32
  def idify( class_name )
31
33
  "#{class_name.to_s.demodulize.underscore}_id"
32
34
  end
35
+
36
+ def supported_options
37
+ [ :class, :class_name ] + additional_options
38
+ end
39
+
40
+ def sanitize_opts( base_class )
41
+ if name.to_s == "object"
42
+ raise YamlBSides::Errors::AssociationError, "#{base_class}: 'object_id' is a reserved keyword in ruby and cannot be overridden"
43
+ end
44
+ invalid_options = (opts.keys - supported_options)
45
+ if invalid_options.present?
46
+ list = invalid_options.map{|o|"'#{o}'"}.to_sentence
47
+ plural = invalid_options.count > 1
48
+ raise YamlBSides::Errors::AssociationError, "#{base_class}: #{list} #{plural ? "are" : "is"} not supported. Please see README for ful details: http://www.github.com/gaorlov/yaml_b_sides"
49
+ end
50
+ end
33
51
  end
34
52
  end
35
53
  end
@@ -5,8 +5,31 @@ module YamlBSides
5
5
  :find
6
6
  end
7
7
 
8
+ def key
9
+ "#{name}_id"
10
+ end
11
+
8
12
  def query( instance )
9
- instance.send "#{name}_id"
13
+ instance.send key
14
+ end
15
+
16
+ def klass( instance )
17
+ if polymorphic?
18
+ class_name = instance.send "#{name}_class"
19
+ class_name.constantize
20
+ else
21
+ super
22
+ end
23
+ end
24
+
25
+ protected
26
+
27
+ def additional_options
28
+ [ :polymorphic ]
29
+ end
30
+
31
+ def polymorphic?
32
+ opts[:polymorphic]
10
33
  end
11
34
  end
12
35
  end
@@ -1,7 +1,7 @@
1
1
  module YamlBSides
2
2
  module Associations
3
3
  class HasMany < Base
4
- include Through
4
+ include Hasable
5
5
 
6
6
  def action
7
7
  :where
@@ -1,7 +1,7 @@
1
1
  module YamlBSides
2
2
  module Associations
3
3
  class HasOne < Base
4
- include Through
4
+ include Hasable
5
5
 
6
6
  def action
7
7
  :find_by
@@ -1,24 +1,42 @@
1
1
  module YamlBSides
2
2
  module Associations
3
- module Through
3
+ module Hasable
4
4
  extend ActiveSupport::Concern
5
5
 
6
6
  included do
7
7
 
8
8
  def query( instance )
9
- unless opts.has_key? :through
10
- { key => instance.id }
11
- else
9
+ if through?
12
10
  { id: target_ids( instance ) }
11
+ elsif as?
12
+ { "#{as}_id" => instance.id }
13
+ else
14
+ { key => instance.id }
13
15
  end
14
16
  end
15
17
 
18
+ def additional_options
19
+ [ :as, :through ]
20
+ end
21
+
16
22
  protected
17
23
 
18
24
  def through
19
25
  opts[:through]
20
26
  end
21
27
 
28
+ def through?
29
+ opts.has_key? :through
30
+ end
31
+
32
+ def as
33
+ opts[:as]
34
+ end
35
+
36
+ def as?
37
+ opts.has_key? :as
38
+ end
39
+
22
40
  def target_ids( instance )
23
41
  intermadiates = Array(instance.send( through ) )
24
42
 
@@ -19,6 +19,7 @@ module YamlBSides
19
19
  logger.info "#{self} successfully loaded data"
20
20
  # let's preemptively index by id so that when we do a find_by id:, or a where id: it won't table scan
21
21
  index :id
22
+ init_indices!
22
23
  rescue => e
23
24
  logger.error "#{self} failed to load data: #{e}"
24
25
  end
@@ -2,5 +2,8 @@ module YamlBSides
2
2
  module Errors
3
3
  class RecordNotFound < StandardError
4
4
  end
5
+
6
+ class AssociationError < StandardError
7
+ end
5
8
  end
6
9
  end
@@ -6,13 +6,13 @@ module YamlBSides
6
6
  class << self
7
7
  def find(id)
8
8
  record = @data[id]
9
- raise Errors::RecordNotFound, "Record not found: #{id}" unless record
9
+ raise Errors::RecordNotFound, "#{self}: Record not found: #{id}" unless record
10
10
  new record
11
11
  end
12
12
 
13
13
  def find_by(params = {})
14
14
  results = where params
15
- raise Errors::RecordNotFound, "Could not find record that matches: #{params.inspect}" if results.empty?
15
+ raise Errors::RecordNotFound, "#{self}: Could not find record that matches: #{params.inspect}" if results.empty?
16
16
  results.first
17
17
  end
18
18
 
@@ -1,3 +1,3 @@
1
1
  module YamlBSides
2
- VERSION = "0.4.3"
2
+ VERSION = "0.5.0"
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: yaml_b_sides
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.3
4
+ version: 0.5.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Greg Orlov
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2016-10-21 00:00:00.000000000 Z
11
+ date: 2016-10-26 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport
@@ -117,7 +117,7 @@ files:
117
117
  - lib/yaml_b_sides/associations/belongs_to.rb
118
118
  - lib/yaml_b_sides/associations/has_many.rb
119
119
  - lib/yaml_b_sides/associations/has_one.rb
120
- - lib/yaml_b_sides/associations/through.rb
120
+ - lib/yaml_b_sides/associations/hasable.rb
121
121
  - lib/yaml_b_sides/base.rb
122
122
  - lib/yaml_b_sides/cacheable.rb
123
123
  - lib/yaml_b_sides/errors.rb