encore 0.1 → 0.2

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: 58e8c5a2cb80f79ec4fdf6afec91a6d67dd1108c
4
- data.tar.gz: f45565ef1a3ae7732237728783146b8a008d4f8e
3
+ metadata.gz: 663990f322867daf2d604b90b17d6f041c5efc38
4
+ data.tar.gz: ea1a8ac943113bad1c8f1d8134221277ce869b77
5
5
  SHA512:
6
- metadata.gz: cd79df1408e83a0792e7723c47fd0d7466140492ca7f10ce36e95902c3e42b992472aa96e27021e07ed9724290ab828983055e9119f79cf7b8caf4be49e2ef79
7
- data.tar.gz: 44b77c571699964d6b3c0b5b6593d660a9e62eac44bc2d9de8e3be72315a57a7fb264a39fd83fc94151171493e53d06be94271241254049c8a5cc68e85441a7a
6
+ metadata.gz: 3ec3e4388cc983e2de0d9c418998d9840db145c4bd89103a087272a2d4429a7661087849d2d1ded571b7c1d8b43a817f6b7fa830070b9abbb03fc74d6f454ac2
7
+ data.tar.gz: 69b5beb8f26e43a18fead232548f9681a292e49887eb36882a0a2d018b716d8ce59126fb9155313c152f80c01c2af91484b1ee0e6538ee8db2708d4f08da985c
data/.gitignore CHANGED
@@ -1 +1,17 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
1
6
  Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
data/README.md CHANGED
@@ -3,13 +3,16 @@
3
3
  <img src="http://i.imgur.com/erXBozp.png" alt="Encore" />
4
4
  </a>
5
5
  <br />
6
- Encore provides serializers and persisters to build <a href="http://jsonapi.org">JSON API</a>-compliant Web services with Ruby on Rails.
6
+ Encore provides serializers and persisters to build <a href="http://jsonapi.org">JSON API</a>-compliant<br /> Web services with Ruby on Rails.
7
7
  <br /><br />
8
+ <a href="https://rubygems.org/gems/encore"><img src="http://img.shields.io/gem/v/encore.svg" /></a>
9
+ <a href="https://travis-ci.org/mirego/encore"><img src="http://img.shields.io/travis/mirego/encore.svg" /></a>
10
+ <a href="https://codeclimate.com/github/mirego/encore"><img src="http://img.shields.io/codeclimate/github/mirego/encore.svg" /></a>
8
11
  </p>
9
12
 
10
13
  ## Installation
11
14
 
12
- Add this line to your application's Gemfile:
15
+ Add this line to your applications Gemfile:
13
16
 
14
17
  ```ruby
15
18
  gem 'encore'
@@ -29,21 +32,21 @@ $ gem install encore
29
32
 
30
33
  ## Disclaimer
31
34
 
32
- Encore is under heavy development at the moment, do not use this gem in production unless you know exactly what you're doing. **Breaking changes** are still being committed.
35
+ As Encore is under heavy development at the moment, we advise against using this gem in production unless you know exactly what youre doing. *Breaking changes* are still being committed.
33
36
 
34
37
  ## Basic serializer usage
35
38
 
36
39
  ### Configure your serializer
37
40
 
38
41
  ```ruby
39
- class CommentSerializer < Encore::Serializer::Base
42
+ class PostSerializer < Encore::Serializer::Base
40
43
  attributes :id, :body, :links
41
44
 
42
45
  # By default, root_key will be the pluralized model
43
46
  # name. If you want to set a custom root_key, you can
44
47
  # do that:
45
48
  def self.root_key
46
- :user_comments
49
+ :blog_posts
47
50
  end
48
51
  end
49
52
  ```
@@ -53,17 +56,17 @@ The `links` attribute is generated by Encore and will return the included associ
53
56
  ### Returning serialized model
54
57
 
55
58
  ```ruby
56
- class CommentsController < ApplicationController
57
- before_action :fetch_comments, only: %i(index)
59
+ class PostsController < ApplicationController
60
+ before_action :fetch_posts, only: %i(index)
58
61
 
59
62
  def index
60
- render json: Encore::Serializer::Instance.new(@comments)
63
+ render json: Encore::Serializer::Instance.new(@posts)
61
64
  end
62
65
 
63
66
  protected
64
67
 
65
- def fetch_comments
66
- @comments = Comment.all
68
+ def fetch_posts
69
+ @posts = Post.all
67
70
  end
68
71
  end
69
72
  ```
@@ -72,17 +75,26 @@ Will result in the following JSON output:
72
75
 
73
76
  ```json
74
77
  {
75
- "comments": [
78
+ "posts": [
76
79
  {
77
80
  "id": "1",
78
- "body": "First!",
79
- "links": {}
81
+ "body": "I enjoy having breakfast in bed. I like waking up to the smell of bacon.",
82
+ "links": {
83
+ "author": {
84
+ "href": "/authors/1",
85
+ "id": "1",
86
+ "type": "authors"
87
+ },
88
+ "comments": {
89
+ "href": "/comments?post_id=1",
90
+ "type": "comments"
91
+ }
92
+ }
80
93
  }
81
94
  ],
82
- "links": {},
83
95
  "linked": {},
84
96
  "meta": {
85
- "comments": {
97
+ "posts": {
86
98
  "page": 1,
87
99
  "count": 1,
88
100
  "page_count": 1,
@@ -94,48 +106,47 @@ Will result in the following JSON output:
94
106
 
95
107
  ### Inclusion
96
108
 
97
- Encore can handle model associations. For example, let's include the `author` in the code sample above.
109
+ Encore can handle model associations. For example, lets include the `comments` in the code sample above.
98
110
 
99
111
  ```ruby
100
- Encore::Serializer::Instance.new(@comments, include: 'author')
112
+ Encore::Serializer::Instance.new(@posts, include: 'comments')
101
113
  ```
102
114
 
103
- Since we don't want all associations to be exposed, we also need to allow the serializer to include the association. To do so, we need to update the `CommentSerializer`.
115
+ Since we dont want all associations to be exposed, we also need to allow the serializer to include the association. To do so, we need to update the `CommentSerializer`.
104
116
 
105
117
  ```ruby
106
- class CommentSerializer < Encore::Serializer::Base
118
+ class PostSerializer < Encore::Serializer::Base
107
119
  # ...
108
120
 
109
121
  def self.can_include
110
- [:author]
122
+ [:author, :comments]
111
123
  end
112
124
  end
113
125
  ```
114
126
 
115
- This will result in the following JSON output:
127
+ Requesting `GET /posts?include=comments` will result in the following JSON output:
116
128
 
117
129
  ```json
118
130
  {
119
- "comments": [
131
+ "posts": [
120
132
  {
121
133
  "id": "1",
122
134
  "body": "First!",
123
135
  "links": {
124
- "author": "1"
136
+ "comments": ["1"],
137
+ "author": {
138
+ "href": "/authors/1",
139
+ "id": 1,
140
+ "type": "authors"
141
+ }
125
142
  }
126
143
  }
127
144
  ],
128
- "links": {
129
- "comments.author": {
130
- "href": "/authors?ids={author.id}",
131
- "type": "user"
132
- }
133
- },
134
145
  "linked": {
135
- "authors": [
146
+ "comments": [
136
147
  {
137
148
  "id": "1",
138
- "name": "John Doe"
149
+ "title": "FIRST!"
139
150
  }
140
151
  ]
141
152
  },
@@ -150,22 +161,18 @@ This will result in the following JSON output:
150
161
  }
151
162
  ```
152
163
 
153
- If you want the `author` the **always** be included when you request a `comment`, update the `CommentSerializer` this way:
164
+ If you want the `comments` to **always** be included when you request a `post`, update the `PostSerializer` this way:
154
165
 
155
166
  ```ruby
156
- class CommentSerializer < Encore::Serializer::Base
157
- attributes :id, :body, :links
167
+ class PostSerializer < Encore::Serializer::Base
168
+ # ...
158
169
 
159
170
  def self.always_include
160
- [:author]
171
+ [:comments]
161
172
  end
162
173
  end
163
174
  ```
164
175
 
165
- ### Pagination
166
-
167
- Lot more work to do here :)
168
-
169
176
  ## License
170
177
 
171
178
  `Encore` is © 2013-2014 [Mirego](http://www.mirego.com) and may be freely distributed under the [New BSD license](http://opensource.org/licenses/BSD-3-Clause). See the [`LICENSE.md`](https://github.com/mirego/encore/blob/master/LICENSE.md) file.
@@ -174,6 +181,6 @@ The hazelnut logo is based on [this lovely icon](http://thenounproject.com/term/
174
181
 
175
182
  ## About Mirego
176
183
 
177
- [Mirego](http://mirego.com) is a team of passionate people who believe that work is a place where you can innovate and have fun. We're a team of [talented people](http://life.mirego.com) who imagine and build beautiful Web and mobile applications. We come together to share ideas and [change the world](http://mirego.org).
184
+ [Mirego](http://mirego.com) is a team of passionate people who believe that work is a place where you can innovate and have fun. Were a team of [talented people](http://life.mirego.com) who imagine and build beautiful Web and mobile applications. We come together to share ideas and [change the world](http://mirego.org).
178
185
 
179
186
  We also [love open-source software](http://open.mirego.com) and we try to give back to the community as much as we can.
@@ -3,6 +3,8 @@ require 'encore/serializer/links_reflection_includer'
3
3
  module Encore
4
4
  module Serializer
5
5
  class Base < ::ActiveModel::Serializer
6
+ attributes :links
7
+
6
8
  def id
7
9
  object.id.to_s
8
10
  end
@@ -25,7 +25,7 @@ module Encore
25
25
 
26
26
  # Build final output
27
27
  output = MainResourceManager.add(@collection, serializer)
28
- output.merge! linked: LinkedResourceManager.add(linked_ids)
28
+ output.merge! linked: LinkedResourceManager.add(linked_ids, @collection)
29
29
  output.merge! meta: MetaManager.add(@collection, serializer, @options)
30
30
 
31
31
  output
@@ -5,12 +5,22 @@ module Encore
5
5
  module LinkedResourceManager
6
6
  extend ActiveSupport::Concern
7
7
 
8
- def self.add(linked_ids)
8
+ def self.add(linked_ids, object)
9
+ included_models = linked_ids.keys.map { |key| key.downcase }
10
+ included_models << object.klass.name.downcase
11
+ included_models << object.klass.name.downcase.pluralize
12
+
9
13
  linked_ids.reduce({}) do |memo, (model, ids)|
10
14
  klass = model.constantize
11
15
  serializer = Utils.fetch_serializer(klass)
12
16
 
13
17
  collection = klass.where(id: ids.to_a)
18
+ available_includes = klass.reflections.map do |key, _|
19
+ next unless included_models.include?(key.to_s)
20
+ key
21
+ end.compact
22
+
23
+ collection = collection.includes(available_includes) unless available_includes.empty?
14
24
  memo.merge! MainResourceManager.add(collection, serializer)
15
25
  end
16
26
  end
@@ -1,3 +1,3 @@
1
1
  module Encore
2
- VERSION = '0.1'
2
+ VERSION = '0.2'
3
3
  end
@@ -64,7 +64,7 @@ describe Encore::Serializer do
64
64
  end
65
65
  end
66
66
 
67
- it { expect(serialized[:linked][:projects]).to eq([{ name: project1.name }, { name: project2.name }]) }
67
+ it { expect(serialized[:linked][:projects]).to eq([{ name: project1.name, links: {} }, { name: project2.name, links: {} }]) }
68
68
  end
69
69
 
70
70
  context 'with and no include' do
@@ -80,6 +80,6 @@ describe Encore::Serializer do
80
80
  end
81
81
  end
82
82
 
83
- it { expect(serialized[:linked][:projects]).to eq([{ name: project1.name }, { name: project2.name }]) }
83
+ it { expect(serialized[:linked][:projects]).to eq([{ name: project1.name, links: {} }, { name: project2.name, links: {} }]) }
84
84
  end
85
85
  end
@@ -64,6 +64,6 @@ describe Encore::Serializer do
64
64
  end
65
65
  end
66
66
 
67
- it { expect(serialized[:linked][:projects]).to eq([{ name: project1.name }, { name: project2.name }]) }
67
+ it { expect(serialized[:linked][:projects]).to eq([{ name: project1.name, links: {} }, { name: project2.name, links: {} }]) }
68
68
  end
69
69
  end
@@ -62,7 +62,7 @@ describe Encore::Serializer do
62
62
 
63
63
  let(:include) { 'project' }
64
64
 
65
- it { expect(serialized[:linked][:projects]).to eq([{ name: project1.name }, { name: project2.name }]) }
65
+ it { expect(serialized[:linked][:projects]).to eq([{ name: project1.name, links: {} }, { name: project2.name, links: {} }]) }
66
66
  end
67
67
 
68
68
  context 'has_many include' do
@@ -81,7 +81,7 @@ describe Encore::Serializer do
81
81
 
82
82
  let(:include) { 'users' }
83
83
 
84
- it { expect(serialized[:linked][:users]).to eq([{ name: 'Allan' }, { name: 'Doe' }, { name: 'Ding' }, { name: 'Bob' }]) }
84
+ it { expect(serialized[:linked][:users]).to eq([{ name: 'Allan', links: {} }, { name: 'Doe', links: {} }, { name: 'Ding', links: {} }, { name: 'Bob', links: {} }]) }
85
85
  end
86
86
 
87
87
  context 'has_one include' do
@@ -98,6 +98,6 @@ describe Encore::Serializer do
98
98
 
99
99
  let(:include) { 'user' }
100
100
 
101
- it { expect(serialized[:linked][:users]).to eq([{ name: 'Allan' }, { name: 'Doe' }]) }
101
+ it { expect(serialized[:linked][:users]).to eq([{ name: 'Allan', links: {} }, { name: 'Doe', links: {} }]) }
102
102
  end
103
103
  end
@@ -0,0 +1,88 @@
1
+ require 'spec_helper'
2
+
3
+ describe Encore::Serializer do
4
+ let(:serializer) { Encore::Serializer::Instance }
5
+ let(:serialized) { serializer.new(objects, page: page, include: include).as_json }
6
+
7
+ let(:page) { 1 }
8
+
9
+ before do
10
+ run_migrations!
11
+ spawn_objects!
12
+ spawn_serializer!
13
+ create_records!
14
+ end
15
+
16
+ let(:run_migrations!) do
17
+ run_migration do
18
+ create_table(:organizations, force: true) do |t|
19
+ t.string :name
20
+ end
21
+ create_table(:users, force: true) do |t|
22
+ t.string :name
23
+ t.integer :project_id
24
+ end
25
+ create_table(:projects, force: true) do |t|
26
+ t.string :name
27
+ t.integer :organization_id
28
+ end
29
+ end
30
+ end
31
+
32
+ let(:spawn_serializer!) do
33
+ spawn_serializer('ProjectSerializer') do
34
+ attributes :name
35
+
36
+ def can_include
37
+ %i(organization user users)
38
+ end
39
+ end
40
+ spawn_serializer('UserSerializer') do
41
+ attributes :name
42
+
43
+ def can_include
44
+ %i(project)
45
+ end
46
+ end
47
+ spawn_serializer('OrganizationSerializer') do
48
+ attributes :name
49
+
50
+ def can_include
51
+ %i(projects)
52
+ end
53
+ end
54
+ end
55
+
56
+ let(:include) { 'project' }
57
+
58
+ let(:objects) { User.all }
59
+ let(:spawn_objects!) do
60
+ spawn_model('User') { belongs_to :project }
61
+ spawn_model('Project') do
62
+ belongs_to :organization
63
+ has_many :users
64
+ end
65
+ spawn_model('Organization') { has_many :projects }
66
+ end
67
+
68
+ let(:org1) { Organization.create name: 'Awesome org' }
69
+ let(:org2) { Organization.create name: 'Medium awesome org' }
70
+ let(:project1) { Project.create name: 'Awesome project', organization: org1 }
71
+ let(:project2) { Project.create name: 'Medium awesome project', organization: org2 }
72
+ let(:user1) { User.create name: 'Alice', project: project1 }
73
+ let(:user2) { User.create name: 'Bob', project: project2 }
74
+ let(:create_records!) do
75
+ user1
76
+ user2
77
+ end
78
+
79
+ context 'already included resource' do
80
+ it { expect(serialized[:linked][:projects][0][:links][:users]).to eq([user1.id.to_s]) }
81
+ it { expect(serialized[:linked][:projects][1][:links][:users]).to eq([user2.id.to_s]) }
82
+ end
83
+
84
+ context 'not included resource' do
85
+ it { expect(serialized[:linked][:projects][0][:links][:organization][:id]).to eq(org1.id.to_s) }
86
+ it { expect(serialized[:linked][:projects][1][:links][:organization][:id]).to eq(org2.id.to_s) }
87
+ end
88
+ end
@@ -0,0 +1,88 @@
1
+ require 'spec_helper'
2
+
3
+ describe Encore::Serializer do
4
+ let(:serializer) { Encore::Serializer::Instance }
5
+ let(:serialized) { serializer.new(objects, page: page, include: include).as_json }
6
+
7
+ let(:page) { 1 }
8
+
9
+ before do
10
+ run_migrations!
11
+ spawn_objects!
12
+ spawn_serializer!
13
+ create_records!
14
+ end
15
+
16
+ let(:run_migrations!) do
17
+ run_migration do
18
+ create_table(:organizations, force: true) do |t|
19
+ t.string :name
20
+ end
21
+ create_table(:users, force: true) do |t|
22
+ t.string :name
23
+ t.integer :project_id
24
+ end
25
+ create_table(:projects, force: true) do |t|
26
+ t.string :name
27
+ t.integer :organization_id
28
+ end
29
+ end
30
+ end
31
+
32
+ let(:spawn_serializer!) do
33
+ spawn_serializer('ProjectSerializer') do
34
+ attributes :name
35
+
36
+ def can_include
37
+ %i(organization user users)
38
+ end
39
+ end
40
+ spawn_serializer('UserSerializer') do
41
+ attributes :name
42
+
43
+ def can_include
44
+ %i(project)
45
+ end
46
+ end
47
+ spawn_serializer('OrganizationSerializer') do
48
+ attributes :name
49
+
50
+ def can_include
51
+ %i(projects)
52
+ end
53
+ end
54
+ end
55
+
56
+ let(:include) { 'project' }
57
+
58
+ let(:objects) { User.all }
59
+ let(:spawn_objects!) do
60
+ spawn_model('User') { belongs_to :project }
61
+ spawn_model('Project') do
62
+ belongs_to :organization
63
+ has_one :user
64
+ end
65
+ spawn_model('Organization') { has_many :projects }
66
+ end
67
+
68
+ let(:org1) { Organization.create name: 'Awesome org' }
69
+ let(:org2) { Organization.create name: 'Medium awesome org' }
70
+ let(:project1) { Project.create name: 'Awesome project', organization: org1 }
71
+ let(:project2) { Project.create name: 'Medium awesome project', organization: org2 }
72
+ let(:user1) { User.create name: 'Alice', project: project1 }
73
+ let(:user2) { User.create name: 'Bob', project: project2 }
74
+ let(:create_records!) do
75
+ user1
76
+ user2
77
+ end
78
+
79
+ context 'already included resource' do
80
+ it { expect(serialized[:linked][:projects][0][:links][:user]).to eq(user1.id.to_s) }
81
+ it { expect(serialized[:linked][:projects][1][:links][:user]).to eq(user2.id.to_s) }
82
+ end
83
+
84
+ context 'not included resource' do
85
+ it { expect(serialized[:linked][:projects][0][:links][:organization][:id]).to eq(org1.id.to_s) }
86
+ it { expect(serialized[:linked][:projects][1][:links][:organization][:id]).to eq(org2.id.to_s) }
87
+ end
88
+ end
@@ -33,5 +33,5 @@ describe Encore::Serializer do
33
33
  end
34
34
 
35
35
  it { expect(serialized[:users].count).to eq(2) }
36
- it { expect(serialized[:users]).to eq([{ name: 'Allan' }, { name: 'Doe' }]) }
36
+ it { expect(serialized[:users]).to eq([{ name: 'Allan', links: {} }, { name: 'Doe', links: {} }]) }
37
37
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: encore
3
3
  version: !ruby/object:Gem::Version
4
- version: '0.1'
4
+ version: '0.2'
5
5
  platform: ruby
6
6
  authors:
7
7
  - Simon Prévost
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-05-29 00:00:00.000000000 Z
11
+ date: 2014-06-03 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activemodel
@@ -207,6 +207,8 @@ files:
207
207
  - spec/encore/serializer/linked/always_include_resources_spec.rb
208
208
  - spec/encore/serializer/linked/can_include_resources_spec.rb
209
209
  - spec/encore/serializer/linked/linked_resources_spec.rb
210
+ - spec/encore/serializer/linked/links_includes/links_includes_has_many_spec.rb
211
+ - spec/encore/serializer/linked/links_includes/links_includes_has_one_spec.rb
210
212
  - spec/encore/serializer/links_resource_spec.rb
211
213
  - spec/encore/serializer/main_meta_spec.rb
212
214
  - spec/encore/serializer/main_resource_spec.rb