somehow_has_relation 0.0.3 → 0.0.4

Sign up to get free protection for your applications and to get access to all the features.
@@ -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