logical_model 0.5.5 → 0.5.7

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