her 0.5.5 → 0.6
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +8 -8
- data/.gitignore +1 -1
- data/README.md +78 -63
- data/UPGRADE.md +21 -0
- data/lib/her/model.rb +2 -1
- data/lib/her/model/associations.rb +17 -54
- data/lib/her/model/associations/association.rb +46 -0
- data/lib/her/model/associations/belongs_to_association.rb +34 -0
- data/lib/her/model/associations/has_many_association.rb +43 -0
- data/lib/her/model/associations/has_one_association.rb +33 -0
- data/lib/her/model/attributes.rb +19 -19
- data/lib/her/model/base.rb +5 -0
- data/lib/her/model/http.rb +17 -21
- data/lib/her/model/orm.rb +11 -35
- data/lib/her/model/parse.rb +4 -12
- data/lib/her/model/paths.rb +3 -2
- data/lib/her/model/relation.rb +113 -0
- data/lib/her/version.rb +1 -1
- data/spec/model/associations_spec.rb +48 -4
- data/spec/model/introspection_spec.rb +1 -1
- data/spec/model/orm_spec.rb +21 -102
- data/spec/model/parse_spec.rb +36 -7
- data/spec/model/paths_spec.rb +3 -3
- data/spec/model/relation_spec.rb +89 -0
- data/spec/spec_helper.rb +1 -0
- data/spec/support/macros/her_macros.rb +17 -0
- data/spec/support/macros/request_macros.rb +19 -0
- metadata +13 -37
- data/examples/grape-and-her/.env.default +0 -3
- data/examples/grape-and-her/Procfile +0 -2
- data/examples/grape-and-her/README.md +0 -27
- data/examples/grape-and-her/api/Gemfile +0 -11
- data/examples/grape-and-her/api/Rakefile +0 -14
- data/examples/grape-and-her/api/app/api.rb +0 -49
- data/examples/grape-and-her/api/app/models/organization.rb +0 -7
- data/examples/grape-and-her/api/app/models/user.rb +0 -9
- data/examples/grape-and-her/api/app/views/organizations/_base.rabl +0 -2
- data/examples/grape-and-her/api/app/views/organizations/index.rabl +0 -3
- data/examples/grape-and-her/api/app/views/organizations/show.rabl +0 -3
- data/examples/grape-and-her/api/app/views/users/_base.rabl +0 -8
- data/examples/grape-and-her/api/app/views/users/index.rabl +0 -3
- data/examples/grape-and-her/api/app/views/users/show.rabl +0 -3
- data/examples/grape-and-her/api/config.ru +0 -5
- data/examples/grape-and-her/api/config/boot.rb +0 -17
- data/examples/grape-and-her/api/config/unicorn.rb +0 -7
- data/examples/grape-and-her/api/db/migrations/001_create_users.rb +0 -11
- data/examples/grape-and-her/api/db/migrations/002_create_organizations.rb +0 -8
- data/examples/grape-and-her/consumer/Gemfile +0 -23
- data/examples/grape-and-her/consumer/app/assets/stylesheets/application.scss +0 -190
- data/examples/grape-and-her/consumer/app/assets/stylesheets/reset.scss +0 -53
- data/examples/grape-and-her/consumer/app/consumer.rb +0 -74
- data/examples/grape-and-her/consumer/app/models/organization.rb +0 -13
- data/examples/grape-and-her/consumer/app/models/user.rb +0 -13
- data/examples/grape-and-her/consumer/app/views/index.haml +0 -9
- data/examples/grape-and-her/consumer/app/views/layout.haml +0 -20
- data/examples/grape-and-her/consumer/app/views/organizations/index.haml +0 -25
- data/examples/grape-and-her/consumer/app/views/organizations/show.haml +0 -11
- data/examples/grape-and-her/consumer/app/views/users/index.haml +0 -33
- data/examples/grape-and-her/consumer/app/views/users/show.haml +0 -9
- data/examples/grape-and-her/consumer/config.ru +0 -20
- data/examples/grape-and-her/consumer/config/boot.rb +0 -30
- data/examples/grape-and-her/consumer/config/unicorn.rb +0 -7
- data/examples/grape-and-her/consumer/lib/response_logger.rb +0 -18
@@ -1,3 +1,8 @@
|
|
1
|
+
require "her/model/associations/association"
|
2
|
+
require "her/model/associations/belongs_to_association"
|
3
|
+
require "her/model/associations/has_many_association"
|
4
|
+
require "her/model/associations/has_one_association"
|
5
|
+
|
1
6
|
module Her
|
2
7
|
module Model
|
3
8
|
# This module adds associations to models
|
@@ -86,29 +91,11 @@ module Her
|
|
86
91
|
}.merge(attrs)
|
87
92
|
(associations[:has_many] ||= []) << attrs
|
88
93
|
|
89
|
-
define_method(name) do
|
90
|
-
|
91
|
-
klass = self.class.her_nearby_class(attrs[:class_name])
|
92
|
-
|
93
|
-
return Her::Collection.new if @attributes.include?(name) && @attributes[name].empty? && method_attrs.empty?
|
94
|
-
|
95
|
-
if @attributes[name].blank? || method_attrs.any?
|
96
|
-
path = begin
|
97
|
-
request_path(method_attrs)
|
98
|
-
rescue Her::Errors::PathError
|
99
|
-
return nil
|
100
|
-
end
|
101
|
-
|
102
|
-
@attributes[name] = klass.get_collection("#{path}#{attrs[:path]}", method_attrs)
|
103
|
-
end
|
104
|
-
|
105
|
-
inverse_of = attrs[:inverse_of] || self.class.name.split('::').last.tableize.singularize
|
94
|
+
define_method(name) do
|
95
|
+
cached_name = :"@_her_association_#{name}"
|
106
96
|
|
107
|
-
|
108
|
-
|
109
|
-
end
|
110
|
-
|
111
|
-
@attributes[name]
|
97
|
+
cached_data = (instance_variable_defined?(cached_name) && instance_variable_get(cached_name))
|
98
|
+
cached_data || instance_variable_set(cached_name, Her::Model::Associations::HasManyAssociation.new(self, attrs))
|
112
99
|
end
|
113
100
|
end
|
114
101
|
|
@@ -139,23 +126,11 @@ module Her
|
|
139
126
|
}.merge(attrs)
|
140
127
|
(associations[:has_one] ||= []) << attrs
|
141
128
|
|
142
|
-
define_method(name) do
|
143
|
-
|
144
|
-
klass = self.class.her_nearby_class(attrs[:class_name])
|
145
|
-
|
146
|
-
return nil if @attributes.include?(name) && @attributes[name].nil? && method_attrs.empty?
|
129
|
+
define_method(name) do
|
130
|
+
cached_name = :"@_her_association_#{name}"
|
147
131
|
|
148
|
-
|
149
|
-
|
150
|
-
request_path(method_attrs)
|
151
|
-
rescue Her::Errors::PathError
|
152
|
-
return nil
|
153
|
-
end
|
154
|
-
|
155
|
-
@attributes[name] = klass.get_resource("#{path}#{attrs[:path]}", method_attrs)
|
156
|
-
end
|
157
|
-
|
158
|
-
@attributes[name]
|
132
|
+
cached_data = (instance_variable_defined?(cached_name) && instance_variable_get(cached_name))
|
133
|
+
cached_data || instance_variable_set(cached_name, Her::Model::Associations::HasOneAssociation.new(self, attrs))
|
159
134
|
end
|
160
135
|
end
|
161
136
|
|
@@ -187,23 +162,11 @@ module Her
|
|
187
162
|
}.merge(attrs)
|
188
163
|
(associations[:belongs_to] ||= []) << attrs
|
189
164
|
|
190
|
-
define_method(name) do
|
191
|
-
|
192
|
-
klass = self.class.her_nearby_class(attrs[:class_name])
|
193
|
-
|
194
|
-
return nil if @attributes.include?(name) && @attributes[name].nil? && method_attrs.empty?
|
195
|
-
|
196
|
-
if @attributes[name].blank? || method_attrs.any?
|
197
|
-
path = begin
|
198
|
-
klass.build_request_path(@attributes.merge(method_attrs.merge(klass.primary_key => @attributes[attrs[:foreign_key].to_sym])))
|
199
|
-
rescue Her::Errors::PathError
|
200
|
-
return nil
|
201
|
-
end
|
202
|
-
|
203
|
-
@attributes[name] = klass.get_resource("#{path}", method_attrs)
|
204
|
-
end
|
165
|
+
define_method(name) do
|
166
|
+
cached_name = :"@_her_association_#{name}"
|
205
167
|
|
206
|
-
|
168
|
+
cached_data = (instance_variable_defined?(cached_name) && instance_variable_get(cached_name))
|
169
|
+
cached_data || instance_variable_set(cached_name, Her::Model::Associations::BelongsToAssociation.new(self, attrs))
|
207
170
|
end
|
208
171
|
end
|
209
172
|
end
|
@@ -0,0 +1,46 @@
|
|
1
|
+
module Her
|
2
|
+
module Model
|
3
|
+
module Associations
|
4
|
+
class Association
|
5
|
+
attr_accessor :query_attrs
|
6
|
+
|
7
|
+
# @private
|
8
|
+
def initialize(parent, opts = {})
|
9
|
+
@parent = parent
|
10
|
+
@opts = opts
|
11
|
+
@query_attrs = {}
|
12
|
+
|
13
|
+
@klass = @parent.class.her_nearby_class(@opts[:class_name])
|
14
|
+
@name = @opts[:name]
|
15
|
+
end
|
16
|
+
|
17
|
+
def where(attrs = {})
|
18
|
+
return self if attrs.blank?
|
19
|
+
self.clone.tap { |a| a.query_attrs = a.query_attrs.merge(attrs) }
|
20
|
+
end
|
21
|
+
alias :all :where
|
22
|
+
|
23
|
+
# @private
|
24
|
+
def nil?
|
25
|
+
fetch.nil?
|
26
|
+
end
|
27
|
+
|
28
|
+
# @private
|
29
|
+
def kind_of?(thing)
|
30
|
+
fetch.kind_of?(thing)
|
31
|
+
end
|
32
|
+
|
33
|
+
# @private
|
34
|
+
def ==(other)
|
35
|
+
fetch.eql?(other)
|
36
|
+
end
|
37
|
+
alias :eql? :==
|
38
|
+
|
39
|
+
# @private
|
40
|
+
def method_missing(method, *args, &blk)
|
41
|
+
fetch.send(method, *args, &blk)
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
module Her
|
2
|
+
module Model
|
3
|
+
module Associations
|
4
|
+
class BelongsToAssociation < Association
|
5
|
+
def build(attributes = {})
|
6
|
+
@klass.new(attributes)
|
7
|
+
end
|
8
|
+
|
9
|
+
def create(attributes = {})
|
10
|
+
resource = build(attributes)
|
11
|
+
@parent.attributes[@name] = resource if resource.save
|
12
|
+
resource
|
13
|
+
end
|
14
|
+
|
15
|
+
def fetch
|
16
|
+
foreign_key_value = @parent.attributes[@opts[:foreign_key].to_sym]
|
17
|
+
return nil if (@parent.attributes.include?(@name) && @parent.attributes[@name].nil? && @query_attrs.empty?) || foreign_key_value.blank?
|
18
|
+
|
19
|
+
if @parent.attributes[@name].blank? || @query_attrs.any?
|
20
|
+
path = begin
|
21
|
+
@klass.build_request_path(@parent.attributes.merge(@query_attrs.merge(@klass.primary_key => foreign_key_value)))
|
22
|
+
rescue Her::Errors::PathError
|
23
|
+
return nil
|
24
|
+
end
|
25
|
+
|
26
|
+
@klass.get_resource("#{path}", @query_attrs)
|
27
|
+
else
|
28
|
+
@parent.attributes[@name]
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
@@ -0,0 +1,43 @@
|
|
1
|
+
module Her
|
2
|
+
module Model
|
3
|
+
module Associations
|
4
|
+
class HasManyAssociation < Association
|
5
|
+
def build(attributes = {})
|
6
|
+
@klass.new(attributes.merge(:"#{@parent.singularized_resource_name}_id" => @parent.id))
|
7
|
+
end
|
8
|
+
|
9
|
+
def create(attributes = {})
|
10
|
+
resource = build(attributes)
|
11
|
+
|
12
|
+
if resource.save
|
13
|
+
@parent.attributes[@name] ||= Her::Collection.new
|
14
|
+
@parent.attributes[@name] << resource
|
15
|
+
end
|
16
|
+
|
17
|
+
resource
|
18
|
+
end
|
19
|
+
|
20
|
+
def fetch
|
21
|
+
return Her::Collection.new if @parent.attributes.include?(@name) && @parent.attributes[@name].empty? && @query_attrs.empty?
|
22
|
+
|
23
|
+
output = if @parent.attributes[@name].blank? || @query_attrs.any?
|
24
|
+
path = begin
|
25
|
+
@parent.request_path(@query_attrs)
|
26
|
+
rescue Her::Errors::PathError
|
27
|
+
return nil
|
28
|
+
end
|
29
|
+
|
30
|
+
@klass.get_collection("#{path}#{@opts[:path]}", @query_attrs)
|
31
|
+
else
|
32
|
+
@parent.attributes[@name]
|
33
|
+
end
|
34
|
+
|
35
|
+
inverse_of = @opts[:inverse_of] || @parent.singularized_resource_name
|
36
|
+
output.each { |entry| entry.send("#{inverse_of}=", @parent) }
|
37
|
+
|
38
|
+
output
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
module Her
|
2
|
+
module Model
|
3
|
+
module Associations
|
4
|
+
class HasOneAssociation < Association
|
5
|
+
def build(attributes = {})
|
6
|
+
@klass.new(attributes.merge(:"#{@parent.singularized_resource_name}_id" => @parent.id))
|
7
|
+
end
|
8
|
+
|
9
|
+
def create(attributes = {})
|
10
|
+
resource = build(attributes)
|
11
|
+
@parent.attributes[@name] = resource if resource.save
|
12
|
+
resource
|
13
|
+
end
|
14
|
+
|
15
|
+
def fetch
|
16
|
+
return nil if @parent.attributes.include?(@name) && @parent.attributes[@name].nil? && @query_attrs.empty?
|
17
|
+
|
18
|
+
if @parent.attributes[@name].blank? || @query_attrs.any?
|
19
|
+
path = begin
|
20
|
+
@parent.request_path(@query_attrs)
|
21
|
+
rescue Her::Errors::PathError
|
22
|
+
return nil
|
23
|
+
end
|
24
|
+
|
25
|
+
@klass.get_resource("#{path}#{@opts[:path]}", @query_attrs)
|
26
|
+
else
|
27
|
+
@parent.attributes[@name]
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
data/lib/her/model/attributes.rb
CHANGED
@@ -40,9 +40,7 @@ module Her
|
|
40
40
|
if setter_method_names.include?(setter_method)
|
41
41
|
model.send(setter_method, value)
|
42
42
|
else
|
43
|
-
if key.is_a?(String)
|
44
|
-
key = key.to_sym
|
45
|
-
end
|
43
|
+
key = key.to_sym if key.is_a?(String)
|
46
44
|
memo[key] = value
|
47
45
|
end
|
48
46
|
memo
|
@@ -145,33 +143,26 @@ module Her
|
|
145
143
|
attributes.each do |attribute|
|
146
144
|
attribute = attribute.to_sym
|
147
145
|
|
148
|
-
define_method
|
146
|
+
define_method attribute do
|
149
147
|
@attributes.include?(attribute) ? @attributes[attribute] : nil
|
150
148
|
end
|
151
149
|
|
152
|
-
define_method "#{attribute}="
|
153
|
-
self.send("#{attribute}_will_change!"
|
150
|
+
define_method :"#{attribute}=" do |value|
|
151
|
+
self.send(:"#{attribute}_will_change!") if @attributes[attribute] != value
|
154
152
|
@attributes[attribute] = value
|
155
153
|
end
|
156
154
|
|
157
|
-
define_method "#{attribute}?"
|
155
|
+
define_method :"#{attribute}?" do
|
158
156
|
@attributes.include?(attribute) && @attributes[attribute].present?
|
159
157
|
end
|
160
158
|
end
|
161
159
|
end
|
162
160
|
|
163
|
-
#
|
164
|
-
def setter_method_names
|
165
|
-
@_her_setter_method_names ||= instance_methods.inject(Set.new) do |memo, method_name|
|
166
|
-
memo << method_name.to_s if method_name.to_s.end_with?('=')
|
167
|
-
memo
|
168
|
-
end
|
169
|
-
end
|
170
|
-
|
161
|
+
# Define the accessor in which the API response errors (obtained from the parsing middleware) will be stored
|
171
162
|
def store_response_errors(value = nil)
|
172
163
|
if @_her_store_response_errors
|
173
164
|
remove_method @_her_store_response_errors
|
174
|
-
remove_method "#{@_her_store_response_errors}="
|
165
|
+
remove_method :"#{@_her_store_response_errors}="
|
175
166
|
end
|
176
167
|
|
177
168
|
@_her_store_response_errors ||= begin
|
@@ -182,13 +173,14 @@ module Her
|
|
182
173
|
@_her_store_response_errors = value
|
183
174
|
|
184
175
|
define_method(@_her_store_response_errors) { @response_errors }
|
185
|
-
define_method("#{@_her_store_response_errors}=") { |value| @response_errors = value }
|
176
|
+
define_method(:"#{@_her_store_response_errors}=") { |value| @response_errors = value }
|
186
177
|
end
|
187
178
|
|
179
|
+
# Define the accessor in which the API response metadata (obtained from the parsing middleware) will be stored
|
188
180
|
def store_metadata(value = nil)
|
189
181
|
if @_her_store_metadata
|
190
182
|
remove_method @_her_store_metadata
|
191
|
-
remove_method "#{@_her_store_metadata}="
|
183
|
+
remove_method :"#{@_her_store_metadata}="
|
192
184
|
end
|
193
185
|
|
194
186
|
@_her_store_metadata ||= begin
|
@@ -199,7 +191,15 @@ module Her
|
|
199
191
|
@_her_store_metadata = value
|
200
192
|
|
201
193
|
define_method(@_her_store_metadata) { @metadata }
|
202
|
-
define_method("#{@_her_store_metadata}=") { |value| @metadata = value }
|
194
|
+
define_method(:"#{@_her_store_metadata}=") { |value| @metadata = value }
|
195
|
+
end
|
196
|
+
|
197
|
+
# @private
|
198
|
+
def setter_method_names
|
199
|
+
@_her_setter_method_names ||= instance_methods.inject(Set.new) do |memo, method_name|
|
200
|
+
memo << method_name.to_s if method_name.to_s.end_with?('=')
|
201
|
+
memo
|
202
|
+
end
|
203
203
|
end
|
204
204
|
end
|
205
205
|
end
|
data/lib/her/model/base.rb
CHANGED
data/lib/her/model/http.rb
CHANGED
@@ -5,21 +5,17 @@ module Her
|
|
5
5
|
extend ActiveSupport::Concern
|
6
6
|
|
7
7
|
module ClassMethods
|
8
|
-
#
|
9
|
-
def
|
10
|
-
@
|
11
|
-
if superclass.respond_to?(:
|
12
|
-
superclass.her_api
|
13
|
-
else
|
14
|
-
Her::API.default_api
|
15
|
-
end
|
8
|
+
# Change which API the model will use to make its HTTP requests
|
9
|
+
def use_api(value = nil)
|
10
|
+
@_her_use_api ||= begin
|
11
|
+
superclass.use_api if superclass.respond_to?(:use_api)
|
16
12
|
end
|
17
|
-
end
|
18
13
|
|
19
|
-
|
20
|
-
|
21
|
-
@_her_api = api
|
14
|
+
return @_her_use_api unless value
|
15
|
+
@_her_use_api = value
|
22
16
|
end
|
17
|
+
alias :her_api :use_api
|
18
|
+
alias :uses_api :use_api
|
23
19
|
|
24
20
|
# Main request wrapper around Her::API. Used to make custom request to the API.
|
25
21
|
# @private
|
@@ -40,10 +36,10 @@ module Her
|
|
40
36
|
# - <method>_collection(path, attrs, &block)
|
41
37
|
# - <method>_resource(path, attrs, &block)
|
42
38
|
# - custom_<method>(path, attrs)
|
43
|
-
|
39
|
+
[:get, :post, :put, :patch, :delete].each do |method|
|
44
40
|
define_method method do |path, attrs={}|
|
45
41
|
path = build_request_path_from_string_or_symbol(path, attrs)
|
46
|
-
send("#{method}_raw"
|
42
|
+
send(:"#{method}_raw", path, attrs) do |parsed_data, response|
|
47
43
|
if parsed_data[:data].is_a?(Array)
|
48
44
|
new_collection(parsed_data)
|
49
45
|
else
|
@@ -52,31 +48,31 @@ module Her
|
|
52
48
|
end
|
53
49
|
end
|
54
50
|
|
55
|
-
define_method "#{method}_raw"
|
51
|
+
define_method :"#{method}_raw" do |path, attrs={}, &block|
|
56
52
|
path = build_request_path_from_string_or_symbol(path, attrs)
|
57
53
|
request(attrs.merge(:_method => method, :_path => path), &block)
|
58
54
|
end
|
59
55
|
|
60
|
-
define_method "#{method}_collection"
|
56
|
+
define_method :"#{method}_collection" do |path=nil, attrs={}|
|
61
57
|
path = build_request_path_from_string_or_symbol(path, attrs)
|
62
|
-
send("#{method}_raw"
|
58
|
+
send(:"#{method}_raw", build_request_path_from_string_or_symbol(path, attrs), attrs) do |parsed_data, response|
|
63
59
|
new_collection(parsed_data)
|
64
60
|
end
|
65
61
|
end
|
66
62
|
|
67
|
-
define_method "#{method}_resource"
|
63
|
+
define_method :"#{method}_resource" do |path, attrs={}|
|
68
64
|
path = build_request_path_from_string_or_symbol(path, attrs)
|
69
|
-
send("#{method}_raw"
|
65
|
+
send(:"#{method}_raw", path, attrs) do |parsed_data, response|
|
70
66
|
new(parse(parsed_data[:data]).merge :_metadata => parsed_data[:metadata], :_errors => parsed_data[:errors])
|
71
67
|
end
|
72
68
|
end
|
73
69
|
|
74
|
-
define_method "custom_#{method}"
|
70
|
+
define_method :"custom_#{method}" do |*paths|
|
75
71
|
metaclass = (class << self; self; end)
|
76
72
|
opts = paths.last.is_a?(Hash) ? paths.pop : Hash.new
|
77
73
|
|
78
74
|
paths.each do |path|
|
79
|
-
metaclass.send(:define_method, path
|
75
|
+
metaclass.send(:define_method, path) do |*attrs|
|
80
76
|
attrs = attrs.first || Hash.new
|
81
77
|
send(method, path, attrs)
|
82
78
|
end
|
data/lib/her/model/orm.rb
CHANGED
@@ -19,7 +19,8 @@ module Her
|
|
19
19
|
@destroyed == true
|
20
20
|
end
|
21
21
|
|
22
|
-
# Save a resource
|
22
|
+
# Save a resource and return `false` if the response is not a successful one or
|
23
|
+
# if there are errors in the resource. Otherwise, return the newly updated resource
|
23
24
|
#
|
24
25
|
# @example Save a resource after fetching it
|
25
26
|
# @user = User.find(1)
|
@@ -33,9 +34,6 @@ module Her
|
|
33
34
|
# @user.save
|
34
35
|
# # Called via POST "/users"
|
35
36
|
def save
|
36
|
-
params = to_params
|
37
|
-
resource = self
|
38
|
-
|
39
37
|
if new?
|
40
38
|
callback = :create
|
41
39
|
method = :post
|
@@ -46,7 +44,7 @@ module Her
|
|
46
44
|
|
47
45
|
run_callbacks callback do
|
48
46
|
run_callbacks :save do
|
49
|
-
self.class.request(
|
47
|
+
self.class.request(to_params.merge(:_method => method, :_path => "#{request_path}")) do |parsed_data, response|
|
50
48
|
assign_attributes(self.class.parse(parsed_data[:data])) if parsed_data[:data].any?
|
51
49
|
self.metadata = parsed_data[:metadata]
|
52
50
|
self.response_errors = parsed_data[:errors]
|
@@ -103,6 +101,7 @@ module Her
|
|
103
101
|
end
|
104
102
|
resource
|
105
103
|
end
|
104
|
+
|
106
105
|
if ids.length > 1 || ids.first.kind_of?(Array)
|
107
106
|
results
|
108
107
|
else
|
@@ -110,39 +109,16 @@ module Her
|
|
110
109
|
end
|
111
110
|
end
|
112
111
|
|
113
|
-
#
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
# # Fetched via GET "/users"
|
118
|
-
def all(params={})
|
119
|
-
request(params.merge(:_method => :get, :_path => "#{build_request_path(params)}")) do |parsed_data, response|
|
120
|
-
new_collection(parsed_data)
|
112
|
+
# Delegate the following methods to `scoped`
|
113
|
+
[:all, :where, :create, :page, :per_page].each do |method|
|
114
|
+
define_method method do |*attrs|
|
115
|
+
scoped.send(method, attrs.first)
|
121
116
|
end
|
122
117
|
end
|
123
118
|
|
124
|
-
#
|
125
|
-
|
126
|
-
|
127
|
-
# @user = User.create({ :fullname => "Tobias Fünke" })
|
128
|
-
# # Called via POST "/users/1"
|
129
|
-
def create(params={})
|
130
|
-
resource = new(params)
|
131
|
-
resource.run_callbacks :create do
|
132
|
-
resource.run_callbacks :save do
|
133
|
-
params = resource.to_params
|
134
|
-
request(params.merge(:_method => :post, :_path => "#{build_request_path(params)}")) do |parsed_data, response|
|
135
|
-
data = parse(parsed_data[:data])
|
136
|
-
resource.instance_eval do
|
137
|
-
assign_attributes(data)
|
138
|
-
@metadata = parsed_data[:metadata]
|
139
|
-
@response_errors = parsed_data[:errors]
|
140
|
-
@changed_attributes.clear if @changed_attributes.present?
|
141
|
-
end
|
142
|
-
end
|
143
|
-
end
|
144
|
-
end
|
145
|
-
resource
|
119
|
+
# @private
|
120
|
+
def scoped
|
121
|
+
Relation.new(self)
|
146
122
|
end
|
147
123
|
|
148
124
|
# Save an existing resource and return it
|