somehow_has_relation 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.
@@ -1,3 +1,3 @@
1
1
  module SomehowHasRelation
2
- VERSION = "0.0.3"
2
+ VERSION = "0.0.4"
3
3
  end
@@ -8,51 +8,58 @@ module SomehowHasRelation
8
8
 
9
9
  module ClassMethods
10
10
  def somehow_has(params={})
11
- remove_const('SOMEHOW_HAS_RELATION') if const_defined?('SOMEHOW_HAS_RELATION')
12
- const_set('SOMEHOW_HAS_RELATION', params)
11
+ if class_variable_defined? :@@somehow_has_relation_options
12
+ class_variable_set(:@@somehow_has_relation_options, class_variable_get(:@@somehow_has_relation_options) << params)
13
+ else
14
+ class_variable_set(:@@somehow_has_relation_options, [params])
15
+ end
16
+
17
+ somehow_has_relation_options = class_variable_get(:@@somehow_has_relation_options)
18
+ times_defined = somehow_has_relation_options.count
19
+ current_options = somehow_has_relation_options[times_defined-1]
13
20
 
14
- prefix = "related"
15
- filter = params[:if]
16
- relation = params[:one] || params[:many]
17
- related = params[:as] || "#{prefix}_#{relation}"
18
- to_flatten = params[:through] && params[:many]
21
+ relation = current_options[:one] || current_options[:many]
22
+ default_method_name = "related_#{relation}"
23
+
24
+ related = current_options[:as] || default_method_name
19
25
 
20
26
  # Dynamic Instance Method related_%{relation_name}
21
27
  define_method(related) do
22
- begin
23
- somehow_got = params[:through] ? somehow_look_for(relation, params[:through]) : send_and_filter(relation, filter)
24
- to_flatten ? somehow_got.flatten : somehow_got
25
- rescue
26
- [] if params[:many]
27
- end
28
- end
29
- end
30
-
31
- def somehow_has_options(key=nil)
32
- if const_defined?('SOMEHOW_HAS_RELATION')
33
- key ? const_get('SOMEHOW_HAS_RELATION')[key] : const_get('SOMEHOW_HAS_RELATION')
28
+ somehow_found_or_recur relation, current_options[:if], current_options
34
29
  end
35
30
  end
36
31
  end
37
32
 
38
33
  module InstanceMethods
39
- def somehow_look_for(relation, through)
34
+ def somehow_recur(relation, through, filter)
40
35
  first_step = send_and_filter(through)
41
- condition = self.class.somehow_has_options(:if)
42
36
 
43
37
  if first_step.is_a? Array
44
- first_step.map{|instance| instance.somehow_keep_looking_for(relation, condition)}
38
+ first_step.map{|instance| instance.somehow_found_or_recur(relation, filter)}
45
39
  else
46
- first_step.somehow_keep_looking_for(relation, condition)
40
+ first_step.somehow_found_or_recur(relation, filter)
47
41
  end
48
42
  end
49
43
 
50
- def somehow_keep_looking_for(relation, condition=nil)
51
- if self.class.somehow_has_options :through
52
- somehow_look_for(relation, self.class.somehow_has_options(:through))
53
- else
54
- condition.nil? ? send_and_filter(relation) : send_and_filter(relation, condition)
44
+ def somehow_found_or_recur(relation, condition=nil, opts=nil)
45
+ opts ||= self.class.send(:class_variable_get, :@@somehow_has_relation_options)
46
+ opts = [opts] unless opts.is_a? Array
47
+
48
+ found = []
49
+
50
+ opts.each do |opt|
51
+ begin
52
+ if opt.has_key?(:through)
53
+ found << somehow_recur(relation, opt[:through], opt[:if])
54
+ else
55
+ return send_and_filter(relation, condition)
56
+ end
57
+ rescue
58
+ found << (opt.has_key?(:many) ? [] : nil)
59
+ end
55
60
  end
61
+
62
+ found.all?{|elem| elem.nil? || (elem.is_a?(Array) && elem.empty?)} ? nil : found.compact.flatten
56
63
  end
57
64
 
58
65
  private
@@ -1,9 +1,8 @@
1
1
  require 'test_helper'
2
2
 
3
3
  class SomehowHasRelationTest < ActiveSupport::TestCase
4
- setup do
5
- Post.somehow_has
6
- end
4
+ setup :init_somehow_has
5
+ teardown :destroy_somehow_has
7
6
 
8
7
  test "somehow_has_relation is a Module" do
9
8
  assert_kind_of Module, SomehowHasRelation
@@ -13,18 +12,17 @@ class SomehowHasRelationTest < ActiveSupport::TestCase
13
12
  assert ActiveRecord::Base.methods.include? :somehow_has.to_s
14
13
  end
15
14
 
16
- test "when somehow_has is called, it should define SOMEHOW_HAS_RELATION" do
17
- assert Post.const_defined?('SOMEHOW_HAS_RELATION')
18
- end
19
-
20
- test "an Hash of parameters should be passed to somehow_has" do
21
- assert_equal Hash, Post::SOMEHOW_HAS_RELATION.class
15
+ test "when somehow_has is called, it should define @@somehow_has_relation_options" do
16
+ assert Post.class_variable_defined?(:@@somehow_has_relation_options)
22
17
  end
23
18
 
24
- test "reinitialize when somehow_has is called more than once" do
19
+ test "an Array of Hash of parameters should be passed to somehow_has" do
25
20
  params = {:newparam => 'newvalue'}
26
21
  Post.somehow_has params
27
- assert_equal params, Post::SOMEHOW_HAS_RELATION
22
+
23
+ assert_equal Array, Post.send(:class_variable_get, :@@somehow_has_relation_options).class
24
+ assert_equal Hash, Post.send(:class_variable_get, :@@somehow_has_relation_options).first.class
25
+ assert_equal params, Post.send(:class_variable_get, :@@somehow_has_relation_options).last
28
26
  end
29
27
 
30
28
  test "relations should work even when somehow_has has not been defined for first step" do
@@ -138,4 +136,22 @@ class SomehowHasRelationTest < ActiveSupport::TestCase
138
136
 
139
137
  assert_equal [], @post.related_comments
140
138
  end
139
+
140
+ private
141
+
142
+ def models
143
+ [Post, Author, Bio, Comment]
144
+ end
145
+
146
+ def init_somehow_has
147
+ models.each do |model|
148
+ model.somehow_has
149
+ end
150
+ end
151
+
152
+ def destroy_somehow_has
153
+ models.each do |model|
154
+ model.send(:remove_class_variable, :@@somehow_has_relation_options)
155
+ end
156
+ end
141
157
  end
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: somehow_has_relation
3
3
  version: !ruby/object:Gem::Version
4
- hash: 25
4
+ hash: 23
5
5
  prerelease:
6
6
  segments:
7
7
  - 0
8
8
  - 0
9
- - 3
10
- version: 0.0.3
9
+ - 4
10
+ version: 0.0.4
11
11
  platform: ruby
12
12
  authors:
13
13
  - Matteo Latini
@@ -15,7 +15,7 @@ autorequire:
15
15
  bindir: bin
16
16
  cert_chain: []
17
17
 
18
- date: 2011-03-21 00:00:00 +01:00
18
+ date: 2011-03-22 00:00:00 +01:00
19
19
  default_executable:
20
20
  dependencies: []
21
21