hal_api-rails 0.2.9 → 0.3.0

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 179cbb4fbac529e58ced08b20fb02ca82bf77bba
4
- data.tar.gz: 1218e1583824ce7f04f686edac03e68bc5e4fa54
3
+ metadata.gz: d5fd9d4857d9ce82ac91cae49c2b239e1ed4ebac
4
+ data.tar.gz: 9f19281381dbdfc58f76b942421c36a7531aacac
5
5
  SHA512:
6
- metadata.gz: 4396211e73d1d968b088a08d7f0d0d6d4ba74f267a2112897393299d94466d72c7e82d17dec1a0b872f59e4fee12913a48b812bfbb63280251cde0d4b98c6d12
7
- data.tar.gz: 32a4f303b627198c99a6d97bc21846dae4283431e08da917b027b85ad648c647e4acc8d4803df59aba8ee18847c9b1df6384fae28a0476900b3612b4ca37283e
6
+ metadata.gz: c8f2041c5eceda12f490af0169b5058ea32b9f782fddeb0c1bbf15ad19973fe2a08dc38f90956accf7557160393a24709e20744ecf53dd4b7fb18d9aee5d60d7
7
+ data.tar.gz: c6c89868387c3416b6ea2ca71114e46a13b33f9a20552a47fab404e31dac0bec96f8af99c97b0f02f4e59d1a072829e0541aa3acd17e0604ccd403a5e8124524
data/README.md CHANGED
@@ -24,7 +24,51 @@ Or install it yourself as:
24
24
 
25
25
  ## Usage
26
26
 
27
- TODO: Write usage instructions here
27
+ This gem provides a number of additions to the `roar` gem HAL support.
28
+
29
+ There are several parts of it that need to be used in your apps:
30
+
31
+ 1) Add to your API controllers:
32
+
33
+ ```ruby
34
+ require 'hal_api/rails'
35
+
36
+ class Api::BaseController < ApplicationController
37
+ include HalApi::Controller
38
+ ...
39
+ end
40
+ ```
41
+
42
+ 2) Add to your `ActiveRecord` models used in your API (perhaps in a base model class):
43
+ ```ruby
44
+ class BaseModel < ActiveRecord::Base
45
+ self.abstract_class = true
46
+
47
+ include RepresentedModel
48
+ end
49
+ ```
50
+
51
+ 3) Use the base representer, define your own CURIEs:
52
+ ```ruby
53
+ class Api::BaseRepresenter < HalApi::Representer
54
+ curies(:prx) do
55
+ [{
56
+ name: :foo,
57
+ href: "http://foo.bar/relation/{rel}",
58
+ templated: true
59
+ }]
60
+ end
61
+
62
+ def index_url_params
63
+ '{?page,per,zoom}'
64
+ end
65
+
66
+ def show_url_params
67
+ '{?zoom}'
68
+ end
69
+ end
70
+ ```
71
+
28
72
 
29
73
  ## Development
30
74
 
@@ -50,7 +50,7 @@ module HalApi::Controller::Actions
50
50
  def index_options
51
51
  valid_params_for_action(:index).tap do |options|
52
52
  options[:_keys] = options.keys
53
- options[:represent_with] = Api::PagedCollectionRepresenter
53
+ options[:represent_with] = HalApi::PagedCollection.representer
54
54
  end
55
55
  end
56
56
 
@@ -77,8 +77,8 @@ module HalApi::Controller::Actions
77
77
 
78
78
  def zoom_param
79
79
  @zoom_param ||= begin
80
- if (zp = params[:zoom]) && zp.present?
81
- zp.split(',').map(&:strip).compact.sort
80
+ if (zp = params[:zoom]) && !zp.nil?
81
+ Array(zp.split(',')).map(&:strip).compact.sort
82
82
  end
83
83
  end
84
84
  end
@@ -10,13 +10,12 @@ module HalApi::Controller::Exceptions
10
10
  wrapper = ::ActionDispatch::ExceptionWrapper.new(env, exception)
11
11
  log_error(env, wrapper)
12
12
 
13
- error = if exception.is_a?(HalApi::Errors::ApiError)
14
- exception
15
- else
16
- e = HalApi::Errors::ApiError.new(exception.message)
17
- e.set_backtrace(exception.backtrace)
18
- e
19
- end
13
+ error = exception
14
+ if !error.is_a?(HalApi::Errors::ApiError)
15
+ error = HalApi::Errors::ApiError.new(error.message).tap do |e|
16
+ e.set_backtrace(error.backtrace)
17
+ end
18
+ end
20
19
 
21
20
  respond_with(
22
21
  error,
@@ -82,15 +82,12 @@ module HalApi::Controller::Resources
82
82
  # Decorations
83
83
 
84
84
  def decorate_query(res)
85
- filtered(paged(sorted(scoped(res))))
85
+ filtered(paged(sorted(scoped(included(res)))))
86
86
  end
87
87
 
88
88
  def filtered(arel)
89
89
  keys = self.class.resources_params || []
90
90
  where_hash = params.slice(*keys)
91
- if where_hash.key?('story_id')
92
- where_hash['piece_id'] = where_hash.delete('story_id')
93
- end
94
91
  where_hash = where_hash.permit(where_hash.keys)
95
92
  arel = arel.where(where_hash) unless where_hash.blank?
96
93
  arel
@@ -13,6 +13,12 @@ class HalApi::PagedCollection
13
13
 
14
14
  def_delegators :request, :params
15
15
 
16
+ class_attribute :representer_class
17
+
18
+ def self.representer
19
+ representer_class || HalApi::PagedCollectionRepresenter
20
+ end
21
+
16
22
  def to_model
17
23
  self
18
24
  end
@@ -0,0 +1,63 @@
1
+ require 'hal_api/representer'
2
+
3
+ class HalApi::PagedCollectionRepresenter < HalApi::Representer
4
+ property :count
5
+ property :total
6
+
7
+ embeds :items, decorator: lambda{|*| item_decorator }, class: lambda{|*| item_class }, zoom: :always
8
+
9
+ link :prev do
10
+ href_url_helper(params.merge(page: represented.prev_page)) unless represented.first_page?
11
+ end
12
+
13
+ link :next do
14
+ href_url_helper(params.merge(page: represented.next_page)) unless represented.last_page?
15
+ end
16
+
17
+ link :first do
18
+ href_url_helper(params.merge(page: nil)) if represented.total_pages > 1
19
+ end
20
+
21
+ link :last do
22
+ href_url_helper(params.merge(page: represented.total_pages)) if represented.total_pages > 1
23
+ end
24
+
25
+ def params
26
+ represented.params
27
+ end
28
+
29
+ def self_url(represented)
30
+ href_url_helper(represented.params)
31
+ end
32
+
33
+ def profile_url(represented)
34
+ model_uri(:collection, represented.item_class)
35
+ end
36
+
37
+ # refactor to use single property, :url, that can be a method name, a string, or a lambda
38
+ # if it is a method name, execute against self - the representer - which has local url helpers methods
39
+ # if it is a sym/string, but self does not respond to it, then just use that string
40
+ # if it is a lambda, execute in the context against the represented.parent (if there is one) or represented
41
+ def href_url_helper(options={})
42
+ if represented_url.nil?
43
+ result = url_for(options.merge(only_path: true)) rescue nil
44
+ if represented.parent
45
+ result ||= polymorphic_path([:api, represented.parent, represented.item_class], options) rescue nil
46
+ end
47
+ result ||= polymorphic_path([:api, represented.item_class], options) rescue nil
48
+ return result
49
+ end
50
+
51
+ if represented_url.respond_to?(:call)
52
+ self.instance_exec(options, &represented_url)
53
+ elsif self.respond_to?(represented_url)
54
+ self.send(represented_url, options)
55
+ else
56
+ represented_url.to_s
57
+ end
58
+ end
59
+
60
+ def represented_url
61
+ @represented_url ||= represented.try(:url)
62
+ end
63
+ end
@@ -1,5 +1,5 @@
1
1
  module HalApi
2
2
  module Rails
3
- VERSION = "0.2.9"
3
+ VERSION = "0.3.0"
4
4
  end
5
5
  end
@@ -15,6 +15,10 @@ module HalApi::RepresentedModel
15
15
  is_root_resource
16
16
  end
17
17
 
18
+ def id_from_url(url)
19
+ Rails.application.routes.recognize_path(url)[:id]
20
+ end
21
+
18
22
  included do
19
23
  extend ActiveModel::Naming unless (method(:model_name) rescue nil)
20
24
  end
@@ -1,4 +1,3 @@
1
- # encoding: utf-8
2
1
  require 'active_support/concern'
3
2
  require 'hal_api/paged_collection'
4
3
 
@@ -10,15 +9,24 @@ module HalApi::Representer::Embeds
10
9
  Representable::Mapper.send(:include, Resources) if !Representable::Mapper.include?(Resources)
11
10
  end
12
11
 
12
+ def normalize_options!(options)
13
+ propagated_options, private_options = super(options)
14
+
15
+ # we want this to propogate, and be available for `skip_property?`, so don't delete
16
+ private_options[:zoom] = options[:zoom] if options.key?(:zoom)
17
+
18
+ [propagated_options, private_options]
19
+ end
20
+
13
21
  module Resources
14
22
 
15
- def skip_property?(binding, options)
16
- super(binding, options) || suppress_embed?(binding, options)
23
+ def skip_property?(binding, private_options)
24
+ super(binding, private_options) || suppress_embed?(binding, private_options)
17
25
  end
18
26
 
19
27
  # embed if zoomed
20
28
  def suppress_embed?(binding, options)
21
- name = (binding[:as] || binding.name).to_s
29
+ name = binding[:as].evaluate(self).to_s || binding.name
22
30
  embedded = !!binding[:embedded]
23
31
 
24
32
  # not embedded, return false - nothing to suppress
@@ -28,7 +36,7 @@ module HalApi::Representer::Embeds
28
36
  !embed_zoomed?(name, binding[:zoom], options[:zoom])
29
37
  end
30
38
 
31
- def embed_zoomed?(name, zoom_def=nil, zoom_param=nil)
39
+ def embed_zoomed?(name, zoom_def = nil, zoom_param = nil)
32
40
  # if the embed in the representer definition has `zoom: :always` defined
33
41
  # always embed it, even if it is in another embed
34
42
  # (this is really meant for collections where embedded items must be included)
@@ -70,7 +78,7 @@ module HalApi::Representer::Embeds
70
78
  per = getter_per == :all ? send(name).count : getter_per
71
79
  HalApi::PagedCollection.new(send(name).page(1).per(per), nil, opts.merge(parent: self))
72
80
  end
73
- options[:decorator] = Api::PagedCollectionRepresenter
81
+ options[:decorator] = HalApi::PagedCollection.representer
74
82
  end
75
83
 
76
84
  property(name, options)
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: hal_api-rails
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.9
4
+ version: 0.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Chris Rhoden
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: exe
11
11
  cert_chain: []
12
- date: 2016-10-11 00:00:00.000000000 Z
12
+ date: 2017-10-27 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: activemodel
@@ -219,6 +219,7 @@ files:
219
219
  - lib/hal_api/controller/resources.rb
220
220
  - lib/hal_api/errors.rb
221
221
  - lib/hal_api/paged_collection.rb
222
+ - lib/hal_api/paged_collection_representer.rb
222
223
  - lib/hal_api/rails.rb
223
224
  - lib/hal_api/rails/version.rb
224
225
  - lib/hal_api/represented_model.rb
@@ -250,7 +251,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
250
251
  version: '0'
251
252
  requirements: []
252
253
  rubyforge_project:
253
- rubygems_version: 2.6.4
254
+ rubygems_version: 2.4.5.2
254
255
  signing_key:
255
256
  specification_version: 4
256
257
  summary: JSON HAL APIs on Rails in the style of PRX