rom-sql 2.0.0.beta2 → 2.0.0.beta3

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.
Files changed (170) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +66 -0
  3. data/lib/rom/plugins/relation/sql/postgres/explain.rb +54 -0
  4. data/lib/rom/sql.rb +1 -1
  5. data/lib/rom/sql/attribute.rb +17 -18
  6. data/lib/rom/sql/errors.rb +3 -0
  7. data/lib/rom/sql/extensions/mysql.rb +1 -1
  8. data/lib/rom/sql/extensions/mysql/type_builder.rb +28 -0
  9. data/lib/rom/sql/extensions/postgres.rb +3 -1
  10. data/lib/rom/sql/extensions/postgres/commands.rb +30 -13
  11. data/lib/rom/sql/extensions/postgres/{attributes_inferrer.rb → type_builder.rb} +24 -28
  12. data/lib/rom/sql/extensions/postgres/type_serializer.rb +39 -0
  13. data/lib/rom/sql/extensions/postgres/types.rb +24 -477
  14. data/lib/rom/sql/extensions/postgres/types/array.rb +163 -0
  15. data/lib/rom/sql/extensions/postgres/types/geometric.rb +135 -0
  16. data/lib/rom/sql/extensions/postgres/types/json.rb +235 -0
  17. data/lib/rom/sql/extensions/postgres/types/network.rb +15 -0
  18. data/lib/rom/sql/extensions/sqlite.rb +1 -1
  19. data/lib/rom/sql/extensions/sqlite/{attributes_inferrer.rb → type_builder.rb} +5 -5
  20. data/lib/rom/sql/extensions/sqlite/types.rb +8 -3
  21. data/lib/rom/sql/foreign_key.rb +17 -0
  22. data/lib/rom/sql/function.rb +86 -8
  23. data/lib/rom/sql/gateway.rb +26 -26
  24. data/lib/rom/sql/index.rb +4 -0
  25. data/lib/rom/sql/migration.rb +3 -3
  26. data/lib/rom/sql/migration/inline_runner.rb +9 -83
  27. data/lib/rom/sql/migration/migrator.rb +35 -12
  28. data/lib/rom/sql/migration/recorder.rb +21 -0
  29. data/lib/rom/sql/migration/runner.rb +115 -0
  30. data/lib/rom/sql/migration/schema_diff.rb +108 -53
  31. data/lib/rom/sql/migration/writer.rb +61 -0
  32. data/lib/rom/sql/relation.rb +2 -1
  33. data/lib/rom/sql/relation/reading.rb +63 -3
  34. data/lib/rom/sql/relation/writing.rb +38 -0
  35. data/lib/rom/sql/schema.rb +9 -3
  36. data/lib/rom/sql/schema/attributes_inferrer.rb +3 -119
  37. data/lib/rom/sql/schema/inferrer.rb +99 -18
  38. data/lib/rom/sql/schema/type_builder.rb +94 -0
  39. data/lib/rom/sql/type_dsl.rb +30 -0
  40. data/lib/rom/sql/type_extensions.rb +11 -6
  41. data/lib/rom/sql/type_serializer.rb +46 -0
  42. data/lib/rom/sql/types.rb +12 -0
  43. data/lib/rom/sql/version.rb +1 -1
  44. metadata +26 -244
  45. data/.codeclimate.yml +0 -15
  46. data/.gitignore +0 -17
  47. data/.rspec +0 -3
  48. data/.travis.yml +0 -39
  49. data/.yardopts +0 -2
  50. data/Gemfile +0 -33
  51. data/Guardfile +0 -24
  52. data/LICENSE.txt +0 -22
  53. data/Rakefile +0 -19
  54. data/circle.yml +0 -10
  55. data/lib/rom/sql/extensions/mysql/attributes_inferrer.rb +0 -10
  56. data/lib/rom/sql/relation/sequel_api.rb +0 -133
  57. data/log/.gitkeep +0 -0
  58. data/rom-sql.gemspec +0 -29
  59. data/spec/extensions/postgres/attribute_spec.rb +0 -217
  60. data/spec/extensions/postgres/integration_spec.rb +0 -59
  61. data/spec/extensions/postgres/types_spec.rb +0 -252
  62. data/spec/extensions/sqlite/types_spec.rb +0 -11
  63. data/spec/fixtures/migrations/20150403090603_create_carrots.rb +0 -8
  64. data/spec/integration/associations/many_to_many/custom_fks_spec.rb +0 -76
  65. data/spec/integration/associations/many_to_many/from_view_spec.rb +0 -88
  66. data/spec/integration/associations/many_to_many_spec.rb +0 -162
  67. data/spec/integration/associations/many_to_one/custom_fks_spec.rb +0 -64
  68. data/spec/integration/associations/many_to_one/from_view_spec.rb +0 -84
  69. data/spec/integration/associations/many_to_one/self_ref_spec.rb +0 -53
  70. data/spec/integration/associations/many_to_one_spec.rb +0 -117
  71. data/spec/integration/associations/one_to_many/custom_fks_spec.rb +0 -54
  72. data/spec/integration/associations/one_to_many/from_view_spec.rb +0 -57
  73. data/spec/integration/associations/one_to_many/self_ref_spec.rb +0 -54
  74. data/spec/integration/associations/one_to_many_spec.rb +0 -86
  75. data/spec/integration/associations/one_to_one_spec.rb +0 -69
  76. data/spec/integration/associations/one_to_one_through_spec.rb +0 -92
  77. data/spec/integration/auto_migrations/errors_spec.rb +0 -31
  78. data/spec/integration/auto_migrations/indexes_spec.rb +0 -253
  79. data/spec/integration/auto_migrations/managing_columns_spec.rb +0 -156
  80. data/spec/integration/auto_migrations/postgres/column_types_spec.rb +0 -63
  81. data/spec/integration/combine_with_spec.rb +0 -43
  82. data/spec/integration/commands/create_spec.rb +0 -304
  83. data/spec/integration/commands/delete_spec.rb +0 -84
  84. data/spec/integration/commands/update_spec.rb +0 -90
  85. data/spec/integration/commands/upsert_spec.rb +0 -83
  86. data/spec/integration/gateway_spec.rb +0 -107
  87. data/spec/integration/migration_spec.rb +0 -55
  88. data/spec/integration/plugins/associates/many_to_many_spec.rb +0 -69
  89. data/spec/integration/plugins/associates_spec.rb +0 -250
  90. data/spec/integration/plugins/auto_restrictions_spec.rb +0 -74
  91. data/spec/integration/relation_schema_spec.rb +0 -271
  92. data/spec/integration/schema/call_spec.rb +0 -24
  93. data/spec/integration/schema/inferrer/mysql_spec.rb +0 -45
  94. data/spec/integration/schema/inferrer/postgres_spec.rb +0 -203
  95. data/spec/integration/schema/inferrer/sqlite_spec.rb +0 -37
  96. data/spec/integration/schema/inferrer_spec.rb +0 -390
  97. data/spec/integration/schema/prefix_spec.rb +0 -16
  98. data/spec/integration/schema/qualified_spec.rb +0 -16
  99. data/spec/integration/schema/rename_spec.rb +0 -21
  100. data/spec/integration/schema/view_spec.rb +0 -29
  101. data/spec/integration/sequel_api_spec.rb +0 -36
  102. data/spec/integration/setup_spec.rb +0 -26
  103. data/spec/integration/support/active_support_notifications_spec.rb +0 -24
  104. data/spec/integration/support/rails_log_subscriber_spec.rb +0 -30
  105. data/spec/integration/wrap_spec.rb +0 -91
  106. data/spec/shared/accounts.rb +0 -48
  107. data/spec/shared/database_setup.rb +0 -70
  108. data/spec/shared/notes.rb +0 -23
  109. data/spec/shared/posts.rb +0 -34
  110. data/spec/shared/puppies.rb +0 -15
  111. data/spec/shared/relations.rb +0 -8
  112. data/spec/shared/users.rb +0 -32
  113. data/spec/shared/users_and_tasks.rb +0 -50
  114. data/spec/spec_helper.rb +0 -122
  115. data/spec/support/env_helper.rb +0 -25
  116. data/spec/support/helpers.rb +0 -24
  117. data/spec/support/oracle/create_users.sql +0 -7
  118. data/spec/support/oracle/set_sys_passwords.sql +0 -2
  119. data/spec/support/test_configuration.rb +0 -16
  120. data/spec/unit/attribute_spec.rb +0 -104
  121. data/spec/unit/function_spec.rb +0 -48
  122. data/spec/unit/gateway_spec.rb +0 -70
  123. data/spec/unit/logger_spec.rb +0 -14
  124. data/spec/unit/migration_tasks_spec.rb +0 -111
  125. data/spec/unit/migrator_spec.rb +0 -25
  126. data/spec/unit/order_dsl_spec.rb +0 -43
  127. data/spec/unit/plugin/associates_spec.rb +0 -94
  128. data/spec/unit/plugin/pagination_spec.rb +0 -91
  129. data/spec/unit/plugin/timestamp_spec.rb +0 -117
  130. data/spec/unit/projection_dsl_spec.rb +0 -110
  131. data/spec/unit/relation/assoc_spec.rb +0 -87
  132. data/spec/unit/relation/associations_spec.rb +0 -27
  133. data/spec/unit/relation/avg_spec.rb +0 -11
  134. data/spec/unit/relation/by_pk_spec.rb +0 -62
  135. data/spec/unit/relation/dataset_spec.rb +0 -50
  136. data/spec/unit/relation/distinct_spec.rb +0 -15
  137. data/spec/unit/relation/exclude_spec.rb +0 -11
  138. data/spec/unit/relation/exist_predicate_spec.rb +0 -25
  139. data/spec/unit/relation/exists_spec.rb +0 -18
  140. data/spec/unit/relation/fetch_spec.rb +0 -21
  141. data/spec/unit/relation/group_spec.rb +0 -61
  142. data/spec/unit/relation/having_spec.rb +0 -22
  143. data/spec/unit/relation/inner_join_spec.rb +0 -158
  144. data/spec/unit/relation/inspect_spec.rb +0 -11
  145. data/spec/unit/relation/instrument_spec.rb +0 -45
  146. data/spec/unit/relation/invert_spec.rb +0 -11
  147. data/spec/unit/relation/left_join_spec.rb +0 -55
  148. data/spec/unit/relation/lock_spec.rb +0 -93
  149. data/spec/unit/relation/map_spec.rb +0 -16
  150. data/spec/unit/relation/max_spec.rb +0 -11
  151. data/spec/unit/relation/min_spec.rb +0 -11
  152. data/spec/unit/relation/order_spec.rb +0 -51
  153. data/spec/unit/relation/pluck_spec.rb +0 -11
  154. data/spec/unit/relation/prefix_spec.rb +0 -29
  155. data/spec/unit/relation/primary_key_spec.rb +0 -27
  156. data/spec/unit/relation/project_spec.rb +0 -24
  157. data/spec/unit/relation/qualified_columns_spec.rb +0 -30
  158. data/spec/unit/relation/qualified_spec.rb +0 -25
  159. data/spec/unit/relation/read_spec.rb +0 -25
  160. data/spec/unit/relation/rename_spec.rb +0 -23
  161. data/spec/unit/relation/right_join_spec.rb +0 -57
  162. data/spec/unit/relation/select_append_spec.rb +0 -21
  163. data/spec/unit/relation/select_spec.rb +0 -40
  164. data/spec/unit/relation/sum_spec.rb +0 -11
  165. data/spec/unit/relation/union_spec.rb +0 -19
  166. data/spec/unit/relation/unique_predicate_spec.rb +0 -18
  167. data/spec/unit/relation/where_spec.rb +0 -133
  168. data/spec/unit/restriction_dsl_spec.rb +0 -34
  169. data/spec/unit/schema_spec.rb +0 -25
  170. data/spec/unit/types_spec.rb +0 -65
@@ -1,21 +0,0 @@
1
- require 'spec_helper'
2
-
3
- RSpec.describe ROM::SQL::Schema, '#rename', :postgres, seeds: false do
4
- include_context 'users'
5
-
6
- before do
7
- conf.relation(:users) do
8
- schema(infer: true)
9
- end
10
- end
11
-
12
- it 'auto-projects a relation with renamed columns' do
13
- expect(relations[:users].schema.rename(id: :user_id, name: :user_name).(relations[:users]).dataset.sql)
14
- .to eql('SELECT "id" AS "user_id", "name" AS "user_name" FROM "users" ORDER BY "users"."id"')
15
- end
16
-
17
- it 'auto-projects a relation with renamed and qualified columns' do
18
- expect(relations[:users].schema.qualified.rename(id: :user_id, name: :user_name).(relations[:users]).dataset.sql)
19
- .to eql('SELECT "users"."id" AS "user_id", "users"."name" AS "user_name" FROM "users" ORDER BY "users"."id"')
20
- end
21
- end
@@ -1,29 +0,0 @@
1
- require 'spec_helper'
2
-
3
- RSpec.describe 'Defining a view using schemas', seeds: false do
4
- include_context 'users'
5
-
6
- with_adapters do
7
- describe 'defining a projected view' do
8
- before do
9
- conf.relation(:users) do
10
- schema(infer: true)
11
-
12
- view(:names) do
13
- schema { project(:name) }
14
- relation { order(:name, :id) }
15
- end
16
- end
17
-
18
- container.relations[:users].insert(name: 'Joe')
19
- container.relations[:users].insert(name: 'Jane')
20
- container.relations[:users].insert(name: 'Jade')
21
- end
22
-
23
- it 'automatically projects a relation view' do
24
- expect(relations[:users].names.to_a)
25
- .to eql([{ name: 'Jade' }, { name: 'Jane' }, { name: 'Joe' }])
26
- end
27
- end
28
- end
29
- end
@@ -1,36 +0,0 @@
1
- require 'spec_helper'
2
-
3
- RSpec.describe 'Using legacy sequel api', :sqlite do
4
- include_context 'users'
5
-
6
- before do
7
- conf.relation(:users) do
8
- include ROM::SQL::Relation::SequelAPI
9
- end
10
-
11
- users.insert(name: 'Jane')
12
- end
13
-
14
- describe '#select' do
15
- it 'selects columns' do
16
- expect(users.select(Sequel.qualify(:users, :id), Sequel.qualify(:users, :name)).first).
17
- to eql(id: 1, name: 'Jane')
18
- end
19
-
20
- it 'supports legacy blocks' do
21
- expect(users.select { count(id).as(:count) }.group(:id).first).to eql(count: 1)
22
- end
23
- end
24
-
25
- describe '#where' do
26
- it 'restricts relation' do
27
- expect(users.where(name: 'Jane').first).to eql(id: 1, name: 'Jane')
28
- end
29
- end
30
-
31
- describe '#order' do
32
- it 'orders relation' do
33
- expect(users.order(Sequel.qualify(:users, :name)).first).to eql(id: 1, name: 'Jane')
34
- end
35
- end
36
- end
@@ -1,26 +0,0 @@
1
- RSpec.describe 'ROM.container' do
2
- include_context 'database setup'
3
-
4
- with_adapters do
5
- let(:rom) do
6
- ROM.container(:sql, uri) do |conf|
7
- conf.default.create_table(:dragons) do
8
- primary_key :id
9
- column :name, String
10
- end
11
-
12
- conf.relation(:dragons) do
13
- schema(infer: true)
14
- end
15
- end
16
- end
17
-
18
- after do
19
- rom.gateways[:default].connection.drop_table(:dragons)
20
- end
21
-
22
- it 'creates tables within the setup block' do
23
- expect(rom.relations[:dragons]).to be_kind_of(ROM::SQL::Relation)
24
- end
25
- end
26
- end
@@ -1,24 +0,0 @@
1
- require 'spec_helper'
2
-
3
- RSpec.describe 'ActiveSupport::Notifications support', :postgres, seeds: false do
4
- before do
5
- ROM::SQL.load_extensions(:active_support_notifications, :rails_log_subscriber)
6
- end
7
-
8
- include_context 'users'
9
-
10
- it 'works' do
11
- container.gateways[:default].use_logger(LOGGER)
12
-
13
- sql = nil
14
-
15
- ActiveSupport::Notifications.subscribe('sql.rom') do |*, payload|
16
- sql = payload[:sql]
17
- end
18
-
19
- query = %(SELECT * FROM "users" WHERE name = 'notification test')
20
- conn.run(query)
21
-
22
- expect(sql).to eql(query)
23
- end
24
- end
@@ -1,30 +0,0 @@
1
- require 'spec_helper'
2
-
3
- require 'active_support/log_subscriber/test_helper'
4
-
5
- RSpec.describe 'Rails log subscriber', :postgres, seeds: false do
6
- before do
7
- ROM::SQL.load_extensions(:active_support_notifications, :rails_log_subscriber)
8
- end
9
-
10
- include ActiveSupport::LogSubscriber::TestHelper
11
-
12
- include_context 'users'
13
-
14
- let(:test_query) do
15
- %(SELECT * FROM "users" WHERE name = 'notification test')
16
- end
17
-
18
- let(:logger) { ActiveSupport::LogSubscriber::TestHelper::MockLogger.new }
19
-
20
- before do
21
- set_logger(logger)
22
- container.gateways[:default].use_logger(logger)
23
- end
24
-
25
- it 'works' do
26
- conn.run(test_query)
27
-
28
- expect(logger.logged(:debug).last).to include(test_query)
29
- end
30
- end
@@ -1,91 +0,0 @@
1
- RSpec.describe ROM::SQL::Wrap do
2
- with_adapters do
3
- include_context 'users and tasks'
4
-
5
- describe '#wrap' do
6
- shared_context 'joined tuple' do
7
- it 'returns nested tuples' do
8
- task_with_user = tasks
9
- .wrap(name)
10
- .where { id.qualified.is(2) }
11
- .one
12
-
13
- expect(task_with_user).to eql(
14
- id: 2, user_id: 1, title: "Jane's task", users_name: "Jane", users_id: 1
15
- )
16
- end
17
-
18
- it 'works with by_pk' do
19
- task_with_user = tasks
20
- .wrap(name)
21
- .by_pk(1)
22
- .one
23
-
24
- expect(task_with_user).
25
- to eql(id: 1, user_id: 2, title: "Joe's task", users_name: "Joe", users_id: 2)
26
- end
27
- end
28
-
29
- context 'using association with inferred relation name' do
30
- before do
31
- conf.relation(:tasks) do
32
- auto_map false
33
-
34
- schema(infer: true) do
35
- associations do
36
- belongs_to :user
37
- end
38
- end
39
- end
40
- end
41
-
42
- include_context 'joined tuple' do
43
- let(:name) { :user }
44
- end
45
- end
46
-
47
- context 'using association with an alias' do
48
- before do
49
- conf.relation(:tasks) do
50
- auto_map false
51
-
52
- schema(infer: true) do
53
- associations do
54
- belongs_to :users, as: :assignee
55
- end
56
- end
57
- end
58
- end
59
-
60
- include_context 'joined tuple' do
61
- let(:name) { :assignee }
62
- end
63
- end
64
-
65
- context 'using association with an aliased relation' do
66
- before do
67
- conf.relation(:tasks) do
68
- auto_map false
69
-
70
- schema(infer: true) do
71
- associations do
72
- belongs_to :users, as: :assignee, relation: :people
73
- end
74
- end
75
- end
76
-
77
- conf.relation(:people) do
78
- auto_map false
79
-
80
- schema(:users, infer: true)
81
- end
82
- end
83
-
84
- include_context 'joined tuple' do
85
- let(:users) { relations[:people] }
86
- let(:name) { :assignee }
87
- end
88
- end
89
- end
90
- end
91
- end
@@ -1,48 +0,0 @@
1
- RSpec.shared_context 'accounts' do
2
- let(:accounts) { container.relations[:accounts] }
3
- let(:cards) { container.relations[:cards] }
4
-
5
- before do
6
- inferrable_relations.concat %i(accounts cards subscriptions)
7
- end
8
-
9
- before do |example|
10
- ctx = self
11
-
12
- conn.create_table :accounts do
13
- primary_key :id
14
- Integer :user_id
15
- String :number
16
-
17
- if ctx.oracle?(example)
18
- Number :balance
19
- else
20
- Decimal :balance, size: [10, 2]
21
- end
22
- end
23
-
24
- conn.create_table :cards do
25
- primary_key :id
26
- Integer :account_id
27
- String :pan
28
- end
29
-
30
- conn.create_table :subscriptions do
31
- primary_key :id
32
- Integer :card_id
33
- String :service
34
- end
35
-
36
- conf.relation(:accounts) { schema(infer: true) }
37
- conf.relation(:cards) { schema(infer: true) }
38
- conf.relation(:subscriptions) { schema(infer: true) }
39
- end
40
-
41
- before do |example|
42
- next if example.metadata[:seeds] == false
43
-
44
- conn[:accounts].insert user_id: 1, number: '42', balance: 10_000.to_d
45
- conn[:cards].insert id: 1, account_id: 1, pan: '*6789'
46
- conn[:subscriptions].insert id: 1, card_id: 1, service: 'aws'
47
- end
48
- end
@@ -1,70 +0,0 @@
1
- RSpec.shared_context 'database setup' do
2
- all_tables = %i(users tasks users_tasks tags task_tags posts puppies
3
- accounts cards subscriptions notes
4
- destinations flights categories user_group
5
- test_inferrence test_bidirectional people dragons
6
- rabbits carrots names schema_migrations)
7
-
8
- cleared_dbs = []
9
-
10
- before do
11
- unless cleared_dbs.include?(conn.database_type)
12
- all_tables.reverse.each { |table| conn.drop_table?(table) }
13
- cleared_dbs << conn.database_type
14
- end
15
- end
16
-
17
- let(:uri) do |example|
18
- meta = example.metadata
19
- adapters = ADAPTERS.select { |adapter| meta[adapter] }
20
-
21
- case adapters.size
22
- when 1 then DB_URIS.fetch(adapters.first)
23
- when 0 then raise 'No adapter specified'
24
- else
25
- raise "Ambiguous adapter configuration, got #{adapters.inspect}"
26
- end
27
- end
28
-
29
- let(:conn) { Sequel.connect(uri) }
30
- let(:database_type) { conn.database_type }
31
- let(:inferrable_relations) { [] }
32
- let(:conf) { TestConfiguration.new(:sql, conn) }
33
- let(:container) { ROM.container(conf) }
34
- let(:relations) { container.relations }
35
- let(:commands) { container.commands }
36
-
37
- before do
38
- conn.loggers << LOGGER
39
- inferrable_relations.each { |name| conf.relation(name) { schema(infer: true) } }
40
- end
41
-
42
- after do
43
- conn.disconnect
44
- # Prevent the auto-reconnect when the test completed
45
- # This will save from hardly reproducible connection run outs
46
- conn.pool.available_connections.freeze
47
- end
48
-
49
- after do
50
- inferrable_relations.reverse.each do |name|
51
- conn.drop_table?(name)
52
- end
53
- end
54
-
55
- def db_true
56
- if database_type == :oracle
57
- 'Y'
58
- else
59
- true
60
- end
61
- end
62
-
63
- def db_false
64
- if database_type == :oracle
65
- 'N'
66
- else
67
- false
68
- end
69
- end
70
- end
data/spec/shared/notes.rb DELETED
@@ -1,23 +0,0 @@
1
- RSpec.shared_context 'notes' do
2
-
3
- before do
4
- inferrable_relations.concat %i(notes)
5
- end
6
-
7
- before do |example|
8
- ctx = self
9
-
10
- conn.create_table :notes do
11
- primary_key :id
12
- foreign_key :user_id, :users
13
- String :text, null: false
14
- # TODO: Remove Oracle's workarounds once inferer can infer not-null timestamps
15
- DateTime :created_at, null: ctx.oracle?(example)
16
- DateTime :updated_at, null: ctx.oracle?(example)
17
- DateTime :completed_at
18
- Date :written
19
- end
20
-
21
- conf.relation(:notes) { schema(infer: true) }
22
- end
23
- end
data/spec/shared/posts.rb DELETED
@@ -1,34 +0,0 @@
1
- RSpec.shared_context 'posts' do
2
- before do
3
- inferrable_relations.concat %i(posts)
4
- end
5
-
6
- before do |example|
7
- conn.create_table :posts do
8
- primary_key :post_id
9
- foreign_key :author_id, :users
10
- String :title
11
- String :body
12
- end
13
-
14
- conf.relation(:posts) { schema(infer: true) }
15
- end
16
-
17
- before do |example|
18
- next if example.metadata[:seeds] == false
19
-
20
- conn[:posts].insert(
21
- post_id: 1,
22
- author_id: 2,
23
- title: "Joe's post",
24
- body: 'Joe wrote sutin'
25
- )
26
-
27
- conn[:posts].insert(
28
- post_id: 2,
29
- author_id: 1,
30
- title: "Jane's post",
31
- body: 'Jane wrote sutin'
32
- )
33
- end
34
- end