encore 0.1 → 0.2

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: 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