her 0.6.6 → 0.6.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 CHANGED
@@ -6,4 +6,15 @@ rvm:
6
6
  - 1.9.2
7
7
  - 1.8.7
8
8
 
9
+ gemfile:
10
+ - Gemfile
11
+ - gemfiles/activemodel-4.0.gemfile
12
+
13
+ matrix:
14
+ exclude:
15
+ - rvm: 1.8.7
16
+ gemfile: gemfiles/activemodel-4.0.gemfile
17
+ - rvm: 1.9.2
18
+ gemfile: gemfiles/activemodel-4.0.gemfile
19
+
9
20
  script: "echo 'COME ON!' && bundle exec rake spec"
data/README.md CHANGED
@@ -367,6 +367,20 @@ You can use the association methods to build new objects and save them.
367
367
  # => [#<Comment id=3 body="Hello world." user_id=1>]
368
368
  ```
369
369
 
370
+ You can also explicitly request a new object via the API when using ``build``. This is useful if you're dealing with default attributes.
371
+
372
+ ```ruby
373
+ class Comment
374
+ include Her::Model
375
+ request_new_object_on_build true
376
+ end
377
+
378
+ @user = User.find(1)
379
+ @user.comments.build(body: "Just a draft")
380
+ # GET "/users/1/comments/new" with `body=Just+a+draft.`
381
+ # => [#<Comment id=nil body="Just a draft" archived=false user_id=1>]
382
+ ```
383
+
370
384
  #### Notes about paths
371
385
 
372
386
  Resources must always have all the required attributes to build their complete path. For example, if you have these models:
@@ -448,7 +462,7 @@ class User
448
462
  end
449
463
  end
450
464
 
451
- @user = User.create(fullname: "Tobias Funke")
465
+ @user = User.create(fullname: "Tobias Fünke")
452
466
  # POST "/users" with `fullname=Tobias+Fünke&internal_id=42`
453
467
 
454
468
  @user = User.find(1)
@@ -891,6 +905,7 @@ These [fine folks](https://github.com/remiprev/her/contributors) helped with Her
891
905
  * [@seanreads](https://github.com/seanreads)
892
906
  * [@jonkarna](https://github.com/jonkarna)
893
907
  * [@aclevy](https://github.com/aclevy)
908
+ * [@stevschmid](https://github.com/stevschmid)
894
909
 
895
910
  ## License
896
911
 
@@ -0,0 +1,5 @@
1
+ source "https://rubygems.org"
2
+
3
+ gemspec path: "../"
4
+
5
+ gem 'activemodel', '~> 4.0.0.rc1'
data/her.gemspec CHANGED
@@ -20,6 +20,7 @@ Gem::Specification.new do |s|
20
20
  s.add_development_dependency "rake", "~> 10.0"
21
21
  s.add_development_dependency "rspec", "~> 2.13"
22
22
  s.add_development_dependency "fivemat", "~> 1.2"
23
+ s.add_development_dependency "json", "~> 1.7.7"
23
24
 
24
25
  s.add_runtime_dependency "activemodel", ">= 3.0.0"
25
26
  s.add_runtime_dependency "activesupport", ">= 3.0.0"
@@ -45,7 +45,7 @@ module Her
45
45
  # new_organization = user.organization.build(:name => "Foo Inc.")
46
46
  # new_organization # => #<Organization name="Foo Inc.">
47
47
  def build(attributes = {})
48
- @klass.new(attributes)
48
+ @klass.build(attributes)
49
49
  end
50
50
 
51
51
  # Create a new object, save it and associate it to the parent
@@ -49,7 +49,7 @@ module Her
49
49
  # new_comment = user.comments.build(:body => "Hello!")
50
50
  # new_comment # => #<Comment user_id=1 body="Hello!">
51
51
  def build(attributes = {})
52
- @klass.new(attributes.merge(:"#{@parent.singularized_resource_name}_id" => @parent.id))
52
+ @klass.build(attributes.merge(:"#{@parent.singularized_resource_name}_id" => @parent.id))
53
53
  end
54
54
 
55
55
  # Create a new object, save it and add it to the associated collection
@@ -44,7 +44,7 @@ module Her
44
44
  # new_role = user.role.build(:title => "moderator")
45
45
  # new_role # => #<Role user_id=1 title="moderator">
46
46
  def build(attributes = {})
47
- @klass.new(attributes.merge(:"#{@parent.singularized_resource_name}_id" => @parent.id))
47
+ @klass.build(attributes.merge(:"#{@parent.singularized_resource_name}_id" => @parent.id))
48
48
  end
49
49
 
50
50
  # Create a new object, save it and associate it to the parent
data/lib/her/model/orm.rb CHANGED
@@ -88,7 +88,7 @@ module Her
88
88
  # User.page(2).all # Called via GET "/users?page=2"
89
89
  def scope(name, code)
90
90
  # Add the scope method to the class
91
- (class << self; self end).define_method(name) do |*args|
91
+ (class << self; self end).send(:define_method, name) do |*args|
92
92
  instance_exec(*args, &code)
93
93
  end
94
94
 
@@ -165,6 +165,24 @@ module Her
165
165
  @method_for[action] = method.to_s.downcase.to_sym
166
166
  end
167
167
 
168
+ # Build a new resource with the given attributes.
169
+ # If the request_new_object_on_build flag is set, the new object is requested via API.
170
+ def build(attributes = {})
171
+ params = attributes
172
+ return self.new(params) unless self.request_new_object_on_build?
173
+
174
+ path = self.build_request_path(params.merge(self.primary_key => 'new'))
175
+ method = self.method_for(:new)
176
+
177
+ resource = nil
178
+ self.request(params.merge(:_method => method, :_path => path)) do |parsed_data, response|
179
+ if response.success?
180
+ resource = self.new_from_parsed_data(parsed_data)
181
+ end
182
+ end
183
+ resource
184
+ end
185
+
168
186
  private
169
187
  # @private
170
188
  def blank_relation
@@ -61,6 +61,23 @@ module Her
61
61
  end
62
62
  alias parse_root_in_json? parse_root_in_json
63
63
 
64
+ # Return or change the value of `request_new_object_on_build`
65
+ #
66
+ # @example
67
+ # class User
68
+ # include Her::Model
69
+ # request_new_object_on_build true
70
+ # end
71
+ def request_new_object_on_build(value = nil)
72
+ @_her_request_new_object_on_build ||= begin
73
+ superclass.request_new_object_on_build if superclass.respond_to?(:request_new_object_on_build)
74
+ end
75
+
76
+ return @_her_request_new_object_on_build unless value
77
+ @_her_request_new_object_on_build = value
78
+ end
79
+ alias request_new_object_on_build? request_new_object_on_build
80
+
64
81
  # Return or change the value of `root_element`. Always defaults to the base name of the class.
65
82
  #
66
83
  # @example
@@ -17,7 +17,7 @@ module Her
17
17
 
18
18
  # Build a new resource
19
19
  def build(attributes = {})
20
- @parent.new(@params.merge(attributes))
20
+ @parent.build(@params.merge(attributes))
21
21
  end
22
22
 
23
23
  # Add a query string parameter
@@ -30,7 +30,7 @@ module Her
30
30
  # @users = User.where(:approved => 1).all
31
31
  # # Fetched via GET "/users?approved=1"
32
32
  def where(params = {})
33
- return self if params.blank? && @_fetch.blank?
33
+ return self if params.blank? && !@_fetch.nil?
34
34
  self.clone.tap do |r|
35
35
  r.params = r.params.merge(params)
36
36
  r.clear_fetch_cache!
data/lib/her/model.rb CHANGED
@@ -53,6 +53,7 @@ module Her
53
53
  method_for :update, :put
54
54
  method_for :find, :get
55
55
  method_for :destroy, :delete
56
+ method_for :new, :get
56
57
 
57
58
  # Define the default primary key
58
59
  primary_key :id
data/lib/her/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Her
2
- VERSION = "0.6.6"
2
+ VERSION = "0.6.7"
3
3
  end
@@ -208,6 +208,43 @@ describe Her::Model::ORM do
208
208
  end
209
209
  end
210
210
 
211
+ context "building resources" do
212
+ context "when request_new_object_on_build is not set (default)" do
213
+ before do
214
+ spawn_model("Foo::User")
215
+ end
216
+
217
+ it "builds a new resource without requesting it" do
218
+ Foo::User.should_not_receive(:request)
219
+ @new_user = Foo::User.build(:fullname => "Tobias Fünke")
220
+ @new_user.new?.should be_true
221
+ @new_user.fullname.should == "Tobias Fünke"
222
+ end
223
+ end
224
+
225
+ context "when request_new_object_on_build is set" do
226
+ before do
227
+ Her::API.setup :url => "https://api.example.com" do |builder|
228
+ builder.use Her::Middleware::FirstLevelParseJSON
229
+ builder.use Faraday::Request::UrlEncoded
230
+ builder.adapter :test do |stub|
231
+ stub.get("/users/new") { |env| ok! :id => nil, :fullname => params(env)[:fullname], :email => "tobias@bluthcompany.com" }
232
+ end
233
+ end
234
+
235
+ spawn_model("Foo::User") { request_new_object_on_build true }
236
+ end
237
+
238
+ it "requests a new resource" do
239
+ Foo::User.should_receive(:request).once.and_call_original
240
+ @new_user = Foo::User.build(:fullname => "Tobias Fünke")
241
+ @new_user.new?.should be_true
242
+ @new_user.fullname.should == "Tobias Fünke"
243
+ @new_user.email.should == "tobias@bluthcompany.com"
244
+ end
245
+ end
246
+ end
247
+
211
248
  context "creating resources" do
212
249
  before do
213
250
  Her::API.setup :url => "https://api.example.com" do |builder|
metadata CHANGED
@@ -1,18 +1,20 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: her
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.6.6
4
+ version: 0.6.7
5
+ prerelease:
5
6
  platform: ruby
6
7
  authors:
7
8
  - Rémi Prévost
8
9
  autorequire:
9
10
  bindir: bin
10
11
  cert_chain: []
11
- date: 2013-05-03 00:00:00.000000000 Z
12
+ date: 2013-05-27 00:00:00.000000000 Z
12
13
  dependencies:
13
14
  - !ruby/object:Gem::Dependency
14
15
  name: rake
15
16
  requirement: !ruby/object:Gem::Requirement
17
+ none: false
16
18
  requirements:
17
19
  - - ~>
18
20
  - !ruby/object:Gem::Version
@@ -20,6 +22,7 @@ dependencies:
20
22
  type: :development
21
23
  prerelease: false
22
24
  version_requirements: !ruby/object:Gem::Requirement
25
+ none: false
23
26
  requirements:
24
27
  - - ~>
25
28
  - !ruby/object:Gem::Version
@@ -27,6 +30,7 @@ dependencies:
27
30
  - !ruby/object:Gem::Dependency
28
31
  name: rspec
29
32
  requirement: !ruby/object:Gem::Requirement
33
+ none: false
30
34
  requirements:
31
35
  - - ~>
32
36
  - !ruby/object:Gem::Version
@@ -34,6 +38,7 @@ dependencies:
34
38
  type: :development
35
39
  prerelease: false
36
40
  version_requirements: !ruby/object:Gem::Requirement
41
+ none: false
37
42
  requirements:
38
43
  - - ~>
39
44
  - !ruby/object:Gem::Version
@@ -41,6 +46,7 @@ dependencies:
41
46
  - !ruby/object:Gem::Dependency
42
47
  name: fivemat
43
48
  requirement: !ruby/object:Gem::Requirement
49
+ none: false
44
50
  requirements:
45
51
  - - ~>
46
52
  - !ruby/object:Gem::Version
@@ -48,13 +54,31 @@ dependencies:
48
54
  type: :development
49
55
  prerelease: false
50
56
  version_requirements: !ruby/object:Gem::Requirement
57
+ none: false
51
58
  requirements:
52
59
  - - ~>
53
60
  - !ruby/object:Gem::Version
54
61
  version: '1.2'
62
+ - !ruby/object:Gem::Dependency
63
+ name: json
64
+ requirement: !ruby/object:Gem::Requirement
65
+ none: false
66
+ requirements:
67
+ - - ~>
68
+ - !ruby/object:Gem::Version
69
+ version: 1.7.7
70
+ type: :development
71
+ prerelease: false
72
+ version_requirements: !ruby/object:Gem::Requirement
73
+ none: false
74
+ requirements:
75
+ - - ~>
76
+ - !ruby/object:Gem::Version
77
+ version: 1.7.7
55
78
  - !ruby/object:Gem::Dependency
56
79
  name: activemodel
57
80
  requirement: !ruby/object:Gem::Requirement
81
+ none: false
58
82
  requirements:
59
83
  - - ! '>='
60
84
  - !ruby/object:Gem::Version
@@ -62,6 +86,7 @@ dependencies:
62
86
  type: :runtime
63
87
  prerelease: false
64
88
  version_requirements: !ruby/object:Gem::Requirement
89
+ none: false
65
90
  requirements:
66
91
  - - ! '>='
67
92
  - !ruby/object:Gem::Version
@@ -69,6 +94,7 @@ dependencies:
69
94
  - !ruby/object:Gem::Dependency
70
95
  name: activesupport
71
96
  requirement: !ruby/object:Gem::Requirement
97
+ none: false
72
98
  requirements:
73
99
  - - ! '>='
74
100
  - !ruby/object:Gem::Version
@@ -76,6 +102,7 @@ dependencies:
76
102
  type: :runtime
77
103
  prerelease: false
78
104
  version_requirements: !ruby/object:Gem::Requirement
105
+ none: false
79
106
  requirements:
80
107
  - - ! '>='
81
108
  - !ruby/object:Gem::Version
@@ -83,6 +110,7 @@ dependencies:
83
110
  - !ruby/object:Gem::Dependency
84
111
  name: faraday
85
112
  requirement: !ruby/object:Gem::Requirement
113
+ none: false
86
114
  requirements:
87
115
  - - ~>
88
116
  - !ruby/object:Gem::Version
@@ -90,6 +118,7 @@ dependencies:
90
118
  type: :runtime
91
119
  prerelease: false
92
120
  version_requirements: !ruby/object:Gem::Requirement
121
+ none: false
93
122
  requirements:
94
123
  - - ~>
95
124
  - !ruby/object:Gem::Version
@@ -97,6 +126,7 @@ dependencies:
97
126
  - !ruby/object:Gem::Dependency
98
127
  name: multi_json
99
128
  requirement: !ruby/object:Gem::Requirement
129
+ none: false
100
130
  requirements:
101
131
  - - ~>
102
132
  - !ruby/object:Gem::Version
@@ -104,6 +134,7 @@ dependencies:
104
134
  type: :runtime
105
135
  prerelease: false
106
136
  version_requirements: !ruby/object:Gem::Requirement
137
+ none: false
107
138
  requirements:
108
139
  - - ~>
109
140
  - !ruby/object:Gem::Version
@@ -125,6 +156,7 @@ files:
125
156
  - README.md
126
157
  - Rakefile
127
158
  - UPGRADE.md
159
+ - gemfiles/activemodel-4.0.gemfile
128
160
  - her.gemspec
129
161
  - lib/her.rb
130
162
  - lib/her/api.rb
@@ -179,26 +211,33 @@ files:
179
211
  homepage: http://her-rb.org
180
212
  licenses:
181
213
  - MIT
182
- metadata: {}
183
214
  post_install_message:
184
215
  rdoc_options: []
185
216
  require_paths:
186
217
  - lib
187
218
  required_ruby_version: !ruby/object:Gem::Requirement
219
+ none: false
188
220
  requirements:
189
221
  - - ! '>='
190
222
  - !ruby/object:Gem::Version
191
223
  version: '0'
224
+ segments:
225
+ - 0
226
+ hash: 1578317715926145011
192
227
  required_rubygems_version: !ruby/object:Gem::Requirement
228
+ none: false
193
229
  requirements:
194
230
  - - ! '>='
195
231
  - !ruby/object:Gem::Version
196
232
  version: '0'
233
+ segments:
234
+ - 0
235
+ hash: 1578317715926145011
197
236
  requirements: []
198
237
  rubyforge_project:
199
- rubygems_version: 2.0.2
238
+ rubygems_version: 1.8.23
200
239
  signing_key:
201
- specification_version: 4
240
+ specification_version: 3
202
241
  summary: A simple Representational State Transfer-based Hypertext Transfer Protocol-powered
203
242
  Object Relational Mapper. Her?
204
243
  test_files:
checksums.yaml DELETED
@@ -1,15 +0,0 @@
1
- ---
2
- !binary "U0hBMQ==":
3
- metadata.gz: !binary |-
4
- NWQ2MzM5ODU1NDgyMmFlODFmNzJiZWRkY2ViMGNhYmY0MDc2YTIyZQ==
5
- data.tar.gz: !binary |-
6
- YTUzYTM2MjY4ZGM2Njc3NDA2ZGRlMDUyYzc4MmNmOGFkODhjNmVlZA==
7
- !binary "U0hBNTEy":
8
- metadata.gz: !binary |-
9
- ZmMyZTY3NTg1ODFjNDBkODYzYWFlZDg4YTZhNTM5Mzk2NzViYzZhZmI3NTQw
10
- OTI5ZDQyOWVjZDg5MzRmNGVhMDYzOTcyYTlkM2MwNWI1NzYzYTIyNDU2NGE1
11
- YTg3MDY3OWU5NTQxODFlYjhiY2Y0MGYwYTVkMjdlZTg3NzUzZmM=
12
- data.tar.gz: !binary |-
13
- ZGE4MjRkN2Y1NjFhYjcxNGE5MTI5ODAzMTdjNGZkMDgzZGNmYmRjODExNDBm
14
- YTU0NDM4YjQ5ZGFhM2I0MTEyZDZlMTlmOTMxZjY4NjNiODVhYTczMjY1Njc0
15
- YzFmMzQxOGU1MmU1ODEyYTY0MDc1YWQxODY2NmMyZmYwYTRlMjQ=