logical_model 0.5.5 → 0.5.7

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/.travis.yml ADDED
@@ -0,0 +1,6 @@
1
+ language: ruby
2
+ bundler_args: --without development production
3
+ rvm:
4
+ - 1.9.2
5
+ - 1.9.3
6
+ - 2.0.0
data/Gemfile CHANGED
@@ -8,15 +8,16 @@ gem "ethon", "0.4.2"
8
8
  gem "kaminari", '~> 0.13.0'
9
9
 
10
10
  group :development, :test do
11
+ gem 'rake'
11
12
  gem 'activerecord'
12
13
  gem "shoulda"
13
- gem "bundler", "~> 1.2.2"
14
+ gem "bundler", ">= 1.2.2"
14
15
  gem "jeweler", "~> 1.6.4"
15
16
  gem "rcov"
16
- gem "sqlite3-ruby"
17
- gem "sinatra", " ~> 1.2.6"
18
- gem "json"
19
- gem 'gemcutter'
17
+ gem "sqlite3-ruby"
18
+ gem "sinatra", " ~> 1.2.6"
19
+ gem "json"
20
+ gem 'gemcutter'
20
21
 
21
22
  gem "rspec-rails"
22
23
 
data/Gemfile.lock CHANGED
@@ -111,7 +111,7 @@ DEPENDENCIES
111
111
  activemodel
112
112
  activerecord
113
113
  activesupport
114
- bundler (~> 1.2.2)
114
+ bundler (>= 1.2.2)
115
115
  ethon (= 0.4.2)
116
116
  gemcutter
117
117
  guard-rspec
@@ -119,6 +119,7 @@ DEPENDENCIES
119
119
  json
120
120
  kaminari (~> 0.13.0)
121
121
  libnotify
122
+ rake
122
123
  rb-inotify
123
124
  rcov
124
125
  rspec-rails
data/README.rdoc CHANGED
@@ -1,3 +1,6 @@
1
+ {<img src="https://badge.fury.io/rb/logical_model.png" alt="Gem Version" />}[http://badge.fury.io/rb/logical_model]
2
+ {<img src="https://travis-ci.org/dwaynemac/logical_model.png" />}[https://travis-ci.org/dwaynemac/logical_model]
3
+ {<img src="https://codeclimate.com/github/dwaynemac/logical_model.png" />}[https://codeclimate.com/github/dwaynemac/logical_model]
1
4
  = logical_model
2
5
 
3
6
  LogicalModel allows to use a RESTfull resources as models.
@@ -57,7 +60,10 @@ In a model file:
57
60
 
58
61
  set_resource_host "remote.server"
59
62
  set_resource_path "/api/remote/path"
60
- # equivalente: set_resource_url "remote.server", "/api/path"
63
+ # equivalent: set_resource_url "remote.server", "/api/remote/path"
64
+
65
+ # optional
66
+ set_api_key(:token, 'asdfasdf') # will add token=asdfasdf to all requests.
61
67
 
62
68
  attribute :id
63
69
  attribute :attribute_a
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.5.5
1
+ 0.5.7
@@ -14,17 +14,27 @@ class LogicalModel
14
14
  attr_class = get_attr_class(key, options)
15
15
 
16
16
  define_method("#{key}=") do |param|
17
- param.stringify_keys!
18
-
19
- instance_variable_set("@#{key}_id", param['id']) if param['id']
20
-
21
- instance = attr_class.new(param)
17
+ if param.is_a?(Hash)
18
+ param.stringify_keys!
19
+ instance_variable_set("@#{key}_id", param['id']) if param['id']
20
+ instance = attr_class.new(param)
21
+ elsif param.is_a?(attr_class)
22
+ instance_variable_set("@#{key}_id", param.id)
23
+ instance = param
24
+ else
25
+ # ...
26
+ end
22
27
 
23
28
  instance_variable_set("@#{key}",instance)
24
29
  end
25
30
 
26
31
  define_method(key) do
27
- eval("@#{key}")
32
+ instance = eval("@#{key}")
33
+ if instance.nil?
34
+ instance = attr_class.find(eval("#{key}_id"))
35
+ instance_variable_set("@#{key}",instance)
36
+ end
37
+ instance
28
38
  end
29
39
 
30
40
  # TODO define_method("#{key}_attribute="){|param| ... }
@@ -72,6 +72,22 @@ class LogicalModel
72
72
  ssl_recommended_environments = %W(production staging)
73
73
  ssl_recommended_environments.include?(defined?(Rails)? Rails.env : ENV['RACK_ENV'] )
74
74
  end
75
+
76
+ # Requests done within the block will go to new path.
77
+ #
78
+ # @example
79
+ # @resource_path # '/comments'
80
+ # do_with_resource_path("users/#{@user_id}/#{@resource_path}"}/") do
81
+ # @resource_path # '/users/23/comments'
82
+ # end
83
+ #
84
+ # @param [String] new_path
85
+ def do_with_resource_path(new_path)
86
+ bkp_path = @resource_path
87
+ @resource_path = new_path
88
+ yield
89
+ @resource_path = bkp_path
90
+ end
75
91
  end
76
92
 
77
93
  end
@@ -14,82 +14,65 @@
14
14
  # end
15
15
  #
16
16
  module TyphoeusFix
17
-
17
+ # Recursively decodes Typhoeus encoded arrays in given Hash.
18
+ #
19
+ # @example Use directly in a Rails controller.
20
+ # class ApplicationController
21
+ # before_filter :decode_typhoeus_arrays
22
+ # end
23
+ #
24
+ # @author Dwayne Macgowan
25
+ #
18
26
  def decode_typhoeus_arrays
19
- deep_decode(params)
27
+ decode!(params)
20
28
  end
21
29
 
22
- # Recursively decode Typhoeus encoded arrays
23
- def deep_decode(hash)
30
+ # Recursively decodes Typhoeus encoded arrays in given Hash.
31
+ #
32
+ # @param hash [Hash]. This Hash will be modified!
33
+ #
34
+ # @return [Hash] Hash with properly decoded nested arrays.
35
+ def decode!(hash)
24
36
  return hash unless hash.is_a?(Hash)
25
37
  hash.each_pair do |key,value|
26
38
  if value.is_a?(Hash)
27
- deep_decode(value)
28
- hash[key] = value.decode_typhoeus_array
39
+ decode!(value)
40
+ hash[key] = convert(value)
29
41
  end
30
42
  end
43
+ hash
31
44
  end
32
- end
33
45
 
34
- # Add Hash#is_typhoeus_array? method
35
- class Hash
46
+ def decode(hash)
47
+ decode!(hash.dup)
48
+ end
49
+
50
+ private
36
51
 
37
- # Checks if hash is an Array encoded as a hash.
38
- # Specifically will check for the hash to have this form: {'0' => v0, '1' => v1, .., 'n' => vN }
39
- # @return [TrueClass]
40
- def im_an_array_typhoeus_encoded?
41
- return false if self.empty?
42
- #return if array is empty or the key is not a valid number
43
- return false if self.empty? || self.keys.first.match(/\A[+-]?\d+?(\.\d+)?\Z/) == nil
44
- self.keys.map {|k| k.to_i}.sort == (0...self.keys.size).map {|i| i}
52
+ # Checks if Hash is an Array encoded as a Hash.
53
+ # Specifically will check for the Hash to have this
54
+ # form: {'0' => v0, '1' => v1, .., 'n' => vN }
55
+ #
56
+ # @param hash [Hash]
57
+ #
58
+ # @return [Boolean] True if its a encoded Array, else false.
59
+ def encoded?(hash)
60
+ return false if hash.empty?
61
+ keys = hash.keys.map{|i| i.to_i if i.respond_to?(:to_i)}.sort
62
+ keys == hash.keys.size.times.to_a
45
63
  end
46
64
 
47
- # If the hash is an array encoded by typhoeus an array is returned
65
+ # If the Hash is an array encoded by typhoeus an array is returned
48
66
  # else the self is returned
49
67
  #
50
- # @see im_an_array_typhoeus_encoded?
68
+ # @param hash [Hash] The Hash to convert into an Array.
51
69
  #
52
- # @return [Array/Hash]
53
- def decode_typhoeus_array
54
- if self.im_an_array_typhoeus_encoded?
55
- Hash[self.sort].values
70
+ # @return [Arraya/Hash]
71
+ def convert(hash)
72
+ if encoded?(hash)
73
+ Hash[hash.sort].values
56
74
  else
57
- self
58
- end
59
- end
60
- end
61
-
62
-
63
-
64
- # Rack Middleware to fix Typhoeus arrays encoding
65
- # TODO this middleware didn't work, when fixed use it and remove filter from ApplicationController
66
- =begin
67
- module Typhoeus
68
- class ArraysDecoder
69
- def initialize(app)
70
- @app = app
71
- end
72
-
73
- def call(env)
74
-
75
- params = env["action_dispatch.request.parameters"]
76
- decode_typho_arrays(params)
77
- env["action_dispatch.request.parameters"] = params
78
- @app.call(env)
79
- end
80
-
81
- private
82
-
83
- # Recursively decode Typhoeus encoded arrays
84
- def decode_typho_arrays(hash)
85
- return hash unless hash.is_a?(Hash)
86
- hash.each_pair do |key,value|
87
- if value.is_a?(Hash)
88
- decode_typho_arrays(value)
89
- hash[key] = value.decode_typhoeus_array
90
- end
91
- end
75
+ hash
92
76
  end
93
77
  end
94
- end
95
- =end
78
+ end
File without changes
@@ -5,11 +5,11 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = "logical_model"
8
- s.version = "0.5.5"
8
+ s.version = "0.5.7"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
11
  s.authors = ["Dwayne Macgowan"]
12
- s.date = "2013-06-18"
12
+ s.date = "2013-07-12"
13
13
  s.description = "LogicalModel allows to use a resource as a model. It is based on web presentation http://www.slideshare.net/ihower/serviceoriented-design-and-implement-with-rails3"
14
14
  s.email = "dwaynemac@gmail.com"
15
15
  s.extra_rdoc_files = [
@@ -18,6 +18,7 @@ Gem::Specification.new do |s|
18
18
  ]
19
19
  s.files = [
20
20
  ".document",
21
+ ".travis.yml",
21
22
  "Gemfile",
22
23
  "Gemfile.lock",
23
24
  "Guardfile",
@@ -42,6 +43,7 @@ Gem::Specification.new do |s|
42
43
  "lib/logical_model/safe_log.rb",
43
44
  "lib/logical_model/url_helper.rb",
44
45
  "lib/typhoeus_fix/array_decoder.rb",
46
+ "log/logical_model.log",
45
47
  "logical_model.gemspec",
46
48
  "models/user.rb",
47
49
  "spec/client_spec.rb",
@@ -64,9 +66,10 @@ Gem::Specification.new do |s|
64
66
  s.add_runtime_dependency(%q<typhoeus>, ["= 0.5.0.alpha"])
65
67
  s.add_runtime_dependency(%q<ethon>, ["= 0.4.2"])
66
68
  s.add_runtime_dependency(%q<kaminari>, ["~> 0.13.0"])
69
+ s.add_development_dependency(%q<rake>, [">= 0"])
67
70
  s.add_development_dependency(%q<activerecord>, [">= 0"])
68
71
  s.add_development_dependency(%q<shoulda>, [">= 0"])
69
- s.add_development_dependency(%q<bundler>, ["~> 1.2.2"])
72
+ s.add_development_dependency(%q<bundler>, [">= 1.2.2"])
70
73
  s.add_development_dependency(%q<jeweler>, ["~> 1.6.4"])
71
74
  s.add_development_dependency(%q<rcov>, [">= 0"])
72
75
  s.add_development_dependency(%q<sqlite3-ruby>, [">= 0"])
@@ -83,9 +86,10 @@ Gem::Specification.new do |s|
83
86
  s.add_dependency(%q<typhoeus>, ["= 0.5.0.alpha"])
84
87
  s.add_dependency(%q<ethon>, ["= 0.4.2"])
85
88
  s.add_dependency(%q<kaminari>, ["~> 0.13.0"])
89
+ s.add_dependency(%q<rake>, [">= 0"])
86
90
  s.add_dependency(%q<activerecord>, [">= 0"])
87
91
  s.add_dependency(%q<shoulda>, [">= 0"])
88
- s.add_dependency(%q<bundler>, ["~> 1.2.2"])
92
+ s.add_dependency(%q<bundler>, [">= 1.2.2"])
89
93
  s.add_dependency(%q<jeweler>, ["~> 1.6.4"])
90
94
  s.add_dependency(%q<rcov>, [">= 0"])
91
95
  s.add_dependency(%q<sqlite3-ruby>, [">= 0"])
@@ -103,9 +107,10 @@ Gem::Specification.new do |s|
103
107
  s.add_dependency(%q<typhoeus>, ["= 0.5.0.alpha"])
104
108
  s.add_dependency(%q<ethon>, ["= 0.4.2"])
105
109
  s.add_dependency(%q<kaminari>, ["~> 0.13.0"])
110
+ s.add_dependency(%q<rake>, [">= 0"])
106
111
  s.add_dependency(%q<activerecord>, [">= 0"])
107
112
  s.add_dependency(%q<shoulda>, [">= 0"])
108
- s.add_dependency(%q<bundler>, ["~> 1.2.2"])
113
+ s.add_dependency(%q<bundler>, [">= 1.2.2"])
109
114
  s.add_dependency(%q<jeweler>, ["~> 1.6.4"])
110
115
  s.add_dependency(%q<rcov>, [">= 0"])
111
116
  s.add_dependency(%q<sqlite3-ruby>, [">= 0"])
data/spec/client_spec.rb CHANGED
@@ -27,6 +27,43 @@ describe "LogicalModel User client" do
27
27
  end
28
28
  end
29
29
 
30
+ describe "belongs_to :account" do
31
+ before do
32
+ class Account < LogicalModel
33
+ attribute :id
34
+ attribute :name
35
+ end
36
+ class User < LogicalModel
37
+ belongs_to :account
38
+ end
39
+
40
+ @account = Account.new(id: 1, name: 'asdf')
41
+ Account.stub(:find).with(1).and_return(@account)
42
+ end
43
+ it "responds to account_id" do
44
+ User.new.should respond_to :account_id
45
+ end
46
+ it "responds to account" do
47
+ User.new.should respond_to :account
48
+ end
49
+ it "allows to set association_id=x" do
50
+ u = User.new
51
+ u.account_id = 1
52
+ u.account.should == @account
53
+ end
54
+ it "allows to set association=Object" do
55
+ u = User.new
56
+ u.account = @account
57
+ u.account_id.should == 1
58
+ end
59
+ it "allows to set association=AttributesHash" do
60
+ u = User.new
61
+ u.account = {id: 3, name: 'account_name'}
62
+ u.account.should be_a Account
63
+ u.account.name.should == 'account_name'
64
+ end
65
+ end
66
+
30
67
  describe "RESTActions" do
31
68
  %W(find async_find paginate async_paginate delete delete_multiple).each do |class_action|
32
69
  it { should respond_to class_action }
@@ -67,6 +104,22 @@ describe "LogicalModel User client" do
67
104
  User.host.should == "new_host"
68
105
  end
69
106
  end
107
+ describe "do_with_resource_path" do
108
+ before do
109
+ User.set_resource_path("/api/v1/users")
110
+ end
111
+ it "changes resource_path within the block" do
112
+ User.do_with_resource_path('/api/v1/accounts/12/users') do
113
+ User.resource_path.should == '/api/v1/accounts/12/users'
114
+ end
115
+ end
116
+ it "restores path after block" do
117
+ User.do_with_resource_path('/api/v1/accounts/12/users') do
118
+ # ...
119
+ end
120
+ User.resource_path.should == "/api/v1/users"
121
+ end
122
+ end
70
123
  end
71
124
 
72
125
  describe "safe_log" do
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: logical_model
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.5.5
4
+ version: 0.5.7
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2013-06-18 00:00:00.000000000 Z
12
+ date: 2013-07-12 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: activemodel
@@ -91,6 +91,22 @@ dependencies:
91
91
  - - ~>
92
92
  - !ruby/object:Gem::Version
93
93
  version: 0.13.0
94
+ - !ruby/object:Gem::Dependency
95
+ name: rake
96
+ requirement: !ruby/object:Gem::Requirement
97
+ none: false
98
+ requirements:
99
+ - - ! '>='
100
+ - !ruby/object:Gem::Version
101
+ version: '0'
102
+ type: :development
103
+ prerelease: false
104
+ version_requirements: !ruby/object:Gem::Requirement
105
+ none: false
106
+ requirements:
107
+ - - ! '>='
108
+ - !ruby/object:Gem::Version
109
+ version: '0'
94
110
  - !ruby/object:Gem::Dependency
95
111
  name: activerecord
96
112
  requirement: !ruby/object:Gem::Requirement
@@ -128,7 +144,7 @@ dependencies:
128
144
  requirement: !ruby/object:Gem::Requirement
129
145
  none: false
130
146
  requirements:
131
- - - ~>
147
+ - - ! '>='
132
148
  - !ruby/object:Gem::Version
133
149
  version: 1.2.2
134
150
  type: :development
@@ -136,7 +152,7 @@ dependencies:
136
152
  version_requirements: !ruby/object:Gem::Requirement
137
153
  none: false
138
154
  requirements:
139
- - - ~>
155
+ - - ! '>='
140
156
  - !ruby/object:Gem::Version
141
157
  version: 1.2.2
142
158
  - !ruby/object:Gem::Dependency
@@ -309,6 +325,7 @@ extra_rdoc_files:
309
325
  - README.rdoc
310
326
  files:
311
327
  - .document
328
+ - .travis.yml
312
329
  - Gemfile
313
330
  - Gemfile.lock
314
331
  - Guardfile
@@ -333,6 +350,7 @@ files:
333
350
  - lib/logical_model/safe_log.rb
334
351
  - lib/logical_model/url_helper.rb
335
352
  - lib/typhoeus_fix/array_decoder.rb
353
+ - log/logical_model.log
336
354
  - logical_model.gemspec
337
355
  - models/user.rb
338
356
  - spec/client_spec.rb
@@ -354,7 +372,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
354
372
  version: '0'
355
373
  segments:
356
374
  - 0
357
- hash: 551778145
375
+ hash: 364483183
358
376
  required_rubygems_version: !ruby/object:Gem::Requirement
359
377
  none: false
360
378
  requirements: