tint 0.0.5 → 0.0.6

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: e0043f48824279d1625572d74b4bd9f9e7c504a4
4
- data.tar.gz: c42e86959edfd7411dba82f08736cb2b0faed36d
3
+ metadata.gz: 3bf5b7492db85d5811d4cef5eacf1ea485d0ff23
4
+ data.tar.gz: a209dcc5a5154cef5ad48ef614b2305cec5e3771
5
5
  SHA512:
6
- metadata.gz: a1d114c2f5254e27c25c41f410a9dd8d3c03b39c75d831acf6765f984a95dceadecdf8048c3f0778fbdf28585e31b67fe240ef46e40c73b3c0dff4a2038e427c
7
- data.tar.gz: d47802117dbf5598db469fa102cf67ee3392909b73cdd7f47948e91ab5af67b54cef53d5839fb9acb3c0712dbc914fc7beb8b0f804c1861666ce82144ffbc26c
6
+ metadata.gz: 1e48ba414b74198f2fe478e9650a3b081fed327f161fc117b19dab7267d41eb66e47c9eb1dfb982e923361bcf8051ee2813d64f2308a5736532284234ab6a236
7
+ data.tar.gz: b60ef0723a9142b51576006e1e9801df62e06f6e000a3f2a31dbccb100d2e5b311fc97394ad9f1cab7aae41a9b37b86f66796e597a0d2f5f562712bacfcc4656
data/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # Tint
2
2
 
3
- Easily define object decorators for JSON APIs using simple declarative syntax
3
+ Easily define object decorators for JSON APIs using simple declarative syntax
4
4
 
5
5
  ## Installation
6
6
 
@@ -22,17 +22,17 @@ You can use Tint by creating a decorator class that inherits from `Tint::Decorat
22
22
 
23
23
  ## Defining attributes
24
24
 
25
- To include methods and attributes available on the decorated object, simply list them using `attributes`.
25
+ To include methods and attributes available on the decorated object, simply list them using `attributes`.
26
26
 
27
27
  ```ruby
28
28
  # decorators/user_decorator.rb
29
29
  class UserDecorator < Tint::Decorator
30
- attributes :username, :first_name, :last_name
30
+ attributes :username, :first_name, :last_name
31
31
  end
32
32
  ```
33
33
 
34
- You can map attributes to different names on the decorator by providing a hash as the final argument
35
-
34
+ You can map attributes to different names on the decorator by providing a hash as the final argument
35
+
36
36
  ```ruby
37
37
  # decorators/user_decorator.rb
38
38
  class UserDecorator < Tint::Decorator
@@ -40,6 +40,29 @@ class UserDecorator < Tint::Decorator
40
40
  end
41
41
  ```
42
42
 
43
+ ## Defining attributes for *_ids
44
+
45
+ The `ids_for` method adds `*Ids` values to a JSON object and ensures the corresponding association is automatically eager loaded:
46
+
47
+ ```ruby
48
+ class ProductDecorator < Tint::Decorator
49
+ attributes :id, :description, :price
50
+
51
+ ids_for :sales # will add a saleIds attribute to the JSON object
52
+ end
53
+ ```
54
+
55
+ It's possible to give the `*Ids` attribute a different name by providing the name of the association as a key-value pair:
56
+
57
+
58
+ ```ruby
59
+ class ProductDecorator < Tint::Decorator
60
+ attributes :id, :description, :price
61
+
62
+ ids_for sales: :purchase_identifiers # will add a purchaseIdentifiers attribute to the JSON object
63
+ end
64
+ ```
65
+
43
66
  ## Defining custom methods
44
67
 
45
68
  Tint will use a decorator instance method in preference to one defined on the decorated object, so it is possible to customise how a particular attribute appears. The original definition of the attribute is available via the `object` instance variable.
@@ -47,9 +70,9 @@ Tint will use a decorator instance method in preference to one defined on the de
47
70
  ```ruby
48
71
  class ProductDecorator < Tint::Decorator
49
72
  attributes :id, :description, :price
50
-
73
+
51
74
  def price
52
- "$" + object.price
75
+ "$" + object.price
53
76
  end
54
77
  end
55
78
  ```
@@ -59,9 +82,9 @@ It's also possible to define methods that are not available on the decorated obj
59
82
  ```ruby
60
83
  class ProductDecorator < Tint::Decorator
61
84
  attributes :id, :description, :on_sale
62
-
85
+
63
86
  def on_sale
64
- SaleItems.include?(object)
87
+ SaleItems.include?(object)
65
88
  end
66
89
  end
67
90
  ```
@@ -79,13 +102,13 @@ end
79
102
  # decorators/user_decorator.rb
80
103
  class UserDecorator < Tint::Decorator
81
104
  attributes :username
82
-
105
+
83
106
  decorates_association :products
84
107
  end
85
108
  ```
86
109
 
87
110
  By default, `decorates_association` uses the name of the association to guess the decorator it should use. In this case it will use `ProductDecorator`, but if you wished to render with `SpecialProductDecorator`, the `with` option may be used:
88
-
111
+
89
112
  ```ruby
90
113
  decorates_association :product, with: SpecialProductDecorator
91
114
  ```
@@ -111,26 +134,26 @@ decorates_associations :previous_address, :current_address, with: AddressDecorat
111
134
  ## Eager loading associations
112
135
 
113
136
  When you declare a new association using `decorates_association` or `decorates_associations`, Tint automatically eager loads the associations when the decorator is rendered as JSON and automatically prevents many N+1 queries. It does this by maintaining a list `eager_loads` which is available on all decorators.
114
-
137
+
115
138
  ```ruby
116
139
  class UserDecorator < Tint::Decorator
117
140
  attributes :username
118
-
141
+
119
142
  decorates_association :products
120
143
  end
121
-
122
-
144
+
145
+
123
146
  UserDecorator.eager_loads # [:products]
124
147
  ```
125
148
 
126
149
  If you need to manually add to the list of associations which are eager loaded for any reason, you can do so using the `eager_load` method
127
-
150
+
128
151
  ```ruby
129
152
  class UserDecorator < Tint::Decorator
130
153
  attributes :username
131
-
154
+
132
155
  decorates_association :products
133
-
156
+
134
157
  eager_load :addresses
135
158
  end
136
159
 
@@ -139,7 +162,7 @@ UserDecorator.eager_loads # [:products, :addresses]
139
162
 
140
163
  ## Decorating a single instance
141
164
 
142
- Tint maintains the interface defined by Draper for decorating objects. To decorate a single object, use the `decorate` method.
165
+ Tint maintains the interface defined by Draper for decorating objects. To decorate a single object, use the `decorate` method.
143
166
 
144
167
  Using the `UserDecorator` defined above:
145
168
 
@@ -150,16 +173,16 @@ class UsersController < ApplicationController
150
173
 
151
174
  def show
152
175
  @user = User.find(params[:id]) #<User username: "john_doe", first_name: "John", surname: "Doe">
153
-
176
+
154
177
  render json: UserDecorator.decorate(@user) # { username: "john_doe", firstName: "John", lastName: "Doe" }
155
178
  end
156
-
179
+
157
180
  end
158
181
  ```
159
182
 
160
183
  `decorate` also accepts an optional has of options. For more information about the supported options, see the [Draper documentation](https://github.com/drapergem/draper#adding-context).
161
-
162
-
184
+
185
+
163
186
  ## Decorating a collection
164
187
 
165
188
  The `decorate_collection` method is used for decorating an instance of ActiveRecord::Relation (or any class that implements the same interface). It accepts all of the same options as the `decorate` method.
@@ -171,17 +194,17 @@ class UsersController < ApplicationController
171
194
 
172
195
  def index
173
196
  @users = User.all
174
-
197
+
175
198
  render json: UserDecorator.decorate_collection(@users) # [ { username: "john_doe", firstName: "John", lastName: "Doe" }, ... ]
176
199
  end
177
-
200
+
178
201
  end
179
202
  ```
180
-
203
+
181
204
  ## Configuration
182
205
 
183
206
  By default, Tint camelizes attribute names, however it's possible to configure Tint to use any of the following capitalization conventions:
184
-
207
+
185
208
  ```ruby
186
209
  Tint.configuration do |config|
187
210
  # attribute_naMe123 ==> attributeNaMe123 (Default)
@@ -157,6 +157,34 @@ module Tint
157
157
  true
158
158
  end
159
159
 
160
+ def ids_for(*options)
161
+ mapped_attrs = options.extract_options!
162
+
163
+ attribute_options = options.map do |association_name|
164
+ association_method = method_name_from_association(association_name)
165
+ eager_load(association_name)
166
+ association_method
167
+ end
168
+
169
+ attribute_options.push(
170
+ mapped_attrs.inject({}) do |memo, key_and_value|
171
+ association_name, value = key_and_value
172
+ memo[value] = method_name_from_association(association_name)
173
+
174
+ eager_load(association_name)
175
+ memo
176
+ end
177
+ )
178
+
179
+ attributes(*attribute_options)
180
+ end
181
+
182
+ private
183
+
184
+ def method_name_from_association(association)
185
+ association.to_s.singularize + '_ids'
186
+ end
187
+
160
188
  def link_delegations_to_object(delegated_attrs)
161
189
  @_override_methods ||= {}
162
190
 
@@ -186,8 +214,6 @@ module Tint
186
214
  end
187
215
  end
188
216
 
189
- private
190
-
191
217
  def expand_schema(schema)
192
218
  if schema.kind_of?(Hash)
193
219
  schema.inject({}) do |memo, (schema_key, schema_value)|
@@ -1,9 +1,5 @@
1
1
  module Tint
2
2
  module JsonConversion
3
- def to_json(options={})
4
- as_json.to_json(options)
5
- end
6
-
7
3
  def as_json(options={})
8
4
  attributes_for_json
9
5
  end
@@ -44,6 +40,10 @@ module Tint
44
40
  end
45
41
  end
46
42
 
43
+ def remove_js_unsafe_chars(string)
44
+ string.gsub(/[\u007f-\u009f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/, '')
45
+ end
46
+
47
47
  def attributes_for_json
48
48
  attribute_list = self.class._attributes
49
49
  override_methods = self.class._override_methods
@@ -74,7 +74,8 @@ module Tint
74
74
  end
75
75
 
76
76
  unless value.nil?
77
- memo[strategy.transform(key)] = value.respond_to?(:as_json) ? value.as_json : value
77
+ json_value = value.respond_to?(:as_json) ? value.as_json : value
78
+ memo[strategy.transform(key)] = json_value.kind_of?(String) ? remove_js_unsafe_chars(json_value) : value
78
79
  end
79
80
 
80
81
  memo
@@ -1,3 +1,3 @@
1
1
  module Tint
2
- VERSION = "0.0.5"
2
+ VERSION = "0.0.6"
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: tint
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.5
4
+ version: 0.0.6
5
5
  platform: ruby
6
6
  authors:
7
7
  - Aleck Greenham
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2017-03-10 00:00:00.000000000 Z
11
+ date: 2017-07-31 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: draper