rom-rails 0.2.1 → 0.3.0.beta1
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 +4 -4
- data/.rubocop.yml +26 -0
- data/CHANGELOG.md +17 -0
- data/README.md +4 -0
- data/lib/generators/rom/commands/templates/create.rb.erb +10 -0
- data/lib/generators/rom/commands/templates/delete.rb.erb +7 -0
- data/lib/generators/rom/commands/templates/update.rb.erb +10 -0
- data/lib/generators/rom/commands_generator.rb +33 -5
- data/lib/generators/rom/form/templates/edit_form.rb.erb +24 -0
- data/lib/generators/rom/form/templates/new_form.rb.erb +24 -0
- data/lib/generators/rom/form_generator.rb +39 -0
- data/lib/generators/rom/mapper/templates/mapper.rb.erb +9 -11
- data/lib/generators/rom/mapper_generator.rb +11 -1
- data/lib/generators/rom/relation/templates/relation.rb.erb +3 -2
- data/lib/generators/rom/relation_generator.rb +16 -1
- data/lib/rom-rails.rb +0 -5
- data/lib/rom/model.rb +7 -90
- data/lib/rom/rails/active_record/configuration.rb +105 -0
- data/lib/rom/rails/configuration.rb +4 -27
- data/lib/rom/rails/model/form.rb +59 -0
- data/lib/rom/rails/model/form/dsl.rb +173 -0
- data/lib/rom/rails/model/params.rb +72 -0
- data/lib/rom/rails/model/validator.rb +74 -0
- data/lib/rom/rails/model/validator/uniqueness_validator.rb +39 -0
- data/lib/rom/rails/railtie.rb +65 -29
- data/lib/rom/rails/version.rb +1 -1
- data/rom-rails.gemspec +3 -1
- data/spec/dummy/app/commands/tasks.rb +5 -0
- data/spec/dummy/app/commands/users.rb +4 -10
- data/spec/dummy/app/controllers/users_controller.rb +30 -0
- data/spec/dummy/app/forms/new_user_form.rb +9 -0
- data/spec/dummy/app/forms/update_user_form.rb +9 -0
- data/spec/dummy/app/forms/user_form.rb +15 -0
- data/spec/dummy/app/mappers/users.rb +6 -6
- data/spec/dummy/app/relations/tasks.rb +9 -0
- data/spec/dummy/app/relations/users.rb +5 -1
- data/spec/dummy/app/views/users/edit.html.erb +6 -0
- data/spec/dummy/app/views/users/new.html.erb +6 -0
- data/spec/dummy/config/routes.rb +5 -1
- data/spec/dummy/db/migrate/20141110205016_add_users.rb +2 -0
- data/spec/dummy/db/migrate/20150202194440_create_tasks.rb +7 -0
- data/spec/dummy/db/schema.rb +8 -8
- data/spec/dummy/spec/features/users_spec.rb +30 -0
- data/spec/dummy/spec/integration/logger_spec.rb +1 -1
- data/spec/dummy/spec/integration/user_commands_spec.rb +2 -18
- data/spec/dummy/spec/integration/user_model_mapping_spec.rb +2 -2
- data/spec/dummy/spec/integration/user_params_spec.rb +30 -15
- data/spec/lib/active_record/configuration_spec.rb +98 -0
- data/spec/lib/generators/commands_generator_spec.rb +54 -14
- data/spec/lib/generators/form_generator_spec.rb +89 -0
- data/spec/lib/generators/mapper_generator_spec.rb +10 -12
- data/spec/lib/generators/relation_generator_spec.rb +16 -6
- data/spec/spec_helper.rb +1 -1
- data/spec/unit/form_spec.rb +297 -0
- data/spec/unit/{model_spec.rb → params_spec.rb} +0 -0
- data/spec/unit/validator_spec.rb +75 -0
- metadata +72 -20
- data/lib/generators/rom/commands/templates/commands.rb.erb +0 -15
- data/spec/dummy/app/controllers/concerns/.keep +0 -0
- data/spec/dummy/app/params/user_params.rb +0 -7
- data/spec/dummy/app/validators/user_validator.rb +0 -3
data/spec/dummy/db/schema.rb
CHANGED
@@ -11,17 +11,17 @@
|
|
11
11
|
#
|
12
12
|
# It's strongly recommended that you check this file into your version control system.
|
13
13
|
|
14
|
-
ActiveRecord::Schema.define(version:
|
15
|
-
create_table "cars", force: true do |_t|
|
16
|
-
end
|
14
|
+
ActiveRecord::Schema.define(version: 20150202194440) do
|
17
15
|
|
18
|
-
create_table "
|
16
|
+
create_table "tasks", force: :cascade do |t|
|
17
|
+
t.string "title"
|
19
18
|
end
|
20
19
|
|
21
|
-
create_table "
|
20
|
+
create_table "users", force: :cascade do |t|
|
21
|
+
t.string "name"
|
22
|
+
t.string "email"
|
23
|
+
t.datetime "created_at"
|
24
|
+
t.datetime "updated_at"
|
22
25
|
end
|
23
26
|
|
24
|
-
create_table "users", force: true do |t|
|
25
|
-
t.string "name"
|
26
|
-
end
|
27
27
|
end
|
@@ -13,6 +13,36 @@ feature 'Users' do
|
|
13
13
|
expect(page).to have_content('Joe')
|
14
14
|
end
|
15
15
|
|
16
|
+
scenario 'I save a new user' do
|
17
|
+
visit '/users/new'
|
18
|
+
|
19
|
+
click_on 'Create User'
|
20
|
+
expect(page).to have_content("can't be blank")
|
21
|
+
|
22
|
+
find('#user_email').set('jade@doe.org')
|
23
|
+
find('#user_name').set('Jade')
|
24
|
+
click_on 'Create User'
|
25
|
+
|
26
|
+
expect(page).to have_content('Jade')
|
27
|
+
expect(page).to have_content('Jane')
|
28
|
+
expect(page).to have_content('Joe')
|
29
|
+
end
|
30
|
+
|
31
|
+
scenario 'I edit an existing user' do
|
32
|
+
jane = rom.relations.users.by_name('Jane').first
|
33
|
+
visit "/users/#{jane[:id]}/edit"
|
34
|
+
|
35
|
+
click_on 'Update User'
|
36
|
+
expect(page).to have_content("can't be blank")
|
37
|
+
|
38
|
+
find('#user_email').set('jane.doe@example.org')
|
39
|
+
find('#user_name').set('Jane Doe')
|
40
|
+
click_on 'Update User'
|
41
|
+
|
42
|
+
expect(page).to have_content('Jane Doe')
|
43
|
+
expect(page).to have_content('Joe')
|
44
|
+
end
|
45
|
+
|
16
46
|
scenario 'I can search users' do
|
17
47
|
visit '/users/search?name=Jane'
|
18
48
|
|
@@ -3,26 +3,10 @@ require 'spec_helper'
|
|
3
3
|
describe 'User commands' do
|
4
4
|
subject(:users) { rom.command(:users) }
|
5
5
|
|
6
|
-
describe 'create' do
|
7
|
-
it 'inserts user with valid params' do
|
8
|
-
result = users.try { create(name: 'Jade') }
|
9
|
-
|
10
|
-
expect(result.value).to eql(id: result.value[:id], name: 'Jade')
|
11
|
-
end
|
12
|
-
|
13
|
-
it 'returns error if params are not valid' do
|
14
|
-
result = users.try { create(name: '') }
|
15
|
-
|
16
|
-
expect(result.value).to be(nil)
|
17
|
-
expect(result.error).to be_instance_of(ROM::Model::ValidationError)
|
18
|
-
expect(result.error.messages[:name]).to include("can't be blank")
|
19
|
-
end
|
20
|
-
end
|
21
|
-
|
22
6
|
describe 'delete' do
|
23
7
|
it 'deletes record' do
|
24
|
-
users.
|
25
|
-
result = users.try { delete(
|
8
|
+
rom.relations.users.insert(name: 'Piotr', email: 'piotr@test.com')
|
9
|
+
result = users.try { users.delete.by_name('Piotr') }
|
26
10
|
|
27
11
|
expect(result.error).to be(nil)
|
28
12
|
end
|
@@ -1,12 +1,12 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
3
|
describe 'User model mapping' do
|
4
|
-
let(:rom) {
|
4
|
+
let(:rom) { ROM.env }
|
5
5
|
|
6
6
|
let(:users) { rom.read(:users) }
|
7
7
|
|
8
8
|
before do
|
9
|
-
rom.
|
9
|
+
rom.relations.users.insert(name: 'Piotr', email: 'piotr@test.com')
|
10
10
|
end
|
11
11
|
|
12
12
|
it 'works' do
|
@@ -5,29 +5,44 @@ describe ROM::Model::Params do
|
|
5
5
|
Class.new do
|
6
6
|
include ROM::Model::Params
|
7
7
|
|
8
|
-
param_key :test
|
9
8
|
attribute :name, String
|
10
|
-
validates :name, presence: true
|
11
9
|
|
12
|
-
|
13
|
-
'Test'
|
14
|
-
end
|
10
|
+
timestamps
|
15
11
|
end
|
16
12
|
end
|
17
13
|
|
18
|
-
describe '
|
19
|
-
it '
|
20
|
-
|
21
|
-
expect(
|
14
|
+
describe '.timestamps' do
|
15
|
+
it 'provides a way to specify timestamps with default values' do
|
16
|
+
expect(params.new.created_at).to be_a(DateTime)
|
17
|
+
expect(params.new.updated_at).to be_a(DateTime)
|
22
18
|
end
|
23
19
|
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
20
|
+
context 'passing in arbritrary names' do
|
21
|
+
it 'excludes :created_at when passing in :updated_at' do
|
22
|
+
params = Class.new {
|
23
|
+
include ROM::Model::Params
|
24
|
+
|
25
|
+
timestamps(:updated_at)
|
26
|
+
}
|
27
|
+
|
28
|
+
model = params.new
|
29
|
+
|
30
|
+
expect(model).not_to respond_to(:created_at)
|
31
|
+
expect(model).to respond_to(:updated_at)
|
32
|
+
end
|
33
|
+
|
34
|
+
it 'accepts multiple timestamp attribute names' do
|
35
|
+
params = Class.new {
|
36
|
+
include ROM::Model::Params
|
37
|
+
|
38
|
+
timestamps(:published_at, :revised_at)
|
39
|
+
}
|
28
40
|
|
29
|
-
|
30
|
-
|
41
|
+
model = params.new
|
42
|
+
|
43
|
+
expect(model).to respond_to(:published_at)
|
44
|
+
expect(model).to respond_to(:revised_at)
|
45
|
+
end
|
31
46
|
end
|
32
47
|
end
|
33
48
|
end
|
@@ -0,0 +1,98 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'rom/rails/active_record/configuration'
|
3
|
+
|
4
|
+
describe ROM::Rails::ActiveRecord::Configuration do
|
5
|
+
let(:root) { Pathname.new('/path/to/app') }
|
6
|
+
|
7
|
+
def uri_for(config)
|
8
|
+
result = read(config)
|
9
|
+
result.is_a?(Hash) ? result[:uri] : result
|
10
|
+
end
|
11
|
+
|
12
|
+
def read(config)
|
13
|
+
described_class.build(config.merge(root: root))
|
14
|
+
end
|
15
|
+
|
16
|
+
def parse(uri)
|
17
|
+
URI.parse(uri.gsub(/^jdbc:/, ''))
|
18
|
+
end
|
19
|
+
|
20
|
+
it 'raises an error without specifying a database'
|
21
|
+
|
22
|
+
context 'with postgresql adapter' do
|
23
|
+
it 'rewrites the scheme' do
|
24
|
+
uri = uri_for(adapter: 'postgresql', database: 'test')
|
25
|
+
expect(parse(uri).scheme).to eql('postgres')
|
26
|
+
end
|
27
|
+
|
28
|
+
it 'does not use jdbc even on jruby' do
|
29
|
+
uri = uri_for(adapter: 'postgresql', database: 'test')
|
30
|
+
expect(uri).to_not start_with('jdbc:')
|
31
|
+
end
|
32
|
+
|
33
|
+
it 'only includes username if no password is given' do
|
34
|
+
uri = uri_for(
|
35
|
+
adapter: 'postgresql',
|
36
|
+
host: 'example.com',
|
37
|
+
database: 'test',
|
38
|
+
username: 'user'
|
39
|
+
)
|
40
|
+
|
41
|
+
expect(parse(uri).userinfo).to eql('user')
|
42
|
+
end
|
43
|
+
|
44
|
+
it 'includes username and password if both are given' do
|
45
|
+
uri = uri_for(
|
46
|
+
adapter: 'postgresql',
|
47
|
+
database: 'test',
|
48
|
+
username: 'user',
|
49
|
+
password: 'password',
|
50
|
+
host: 'example.com'
|
51
|
+
)
|
52
|
+
|
53
|
+
expect(parse(uri).userinfo).to eql('user:password')
|
54
|
+
end
|
55
|
+
|
56
|
+
it 'omits userinfo if neither username nor password are given' do
|
57
|
+
uri = uri_for(adapter: 'postgresql', database: 'test')
|
58
|
+
expect(parse(uri).userinfo).to be_nil
|
59
|
+
end
|
60
|
+
|
61
|
+
it 'properly handles configuration without a host' do
|
62
|
+
uri = uri_for(adapter: 'postgresql', database: 'test')
|
63
|
+
expect(uri).to eql('postgres:///test')
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
context 'with mysql adapter' do
|
68
|
+
it 'sets default password to an empty string' do
|
69
|
+
uri = uri_for(adapter: 'mysql', database: 'test', username: 'root', host: 'example.com')
|
70
|
+
expect(parse(uri).userinfo).to eql('root:')
|
71
|
+
end
|
72
|
+
|
73
|
+
it 'uses jdbc only on jruby' do
|
74
|
+
uri = uri_for(adapter: 'mysql', database: 'test')
|
75
|
+
expect(uri.starts_with?('jdbc:')).to be(RUBY_ENGINE == 'jruby')
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
context 'with sqlite3 adapter' do
|
80
|
+
let(:database) { Pathname.new('db/development.sqlite3') }
|
81
|
+
let(:config) { { adapter: adapter, database: database } }
|
82
|
+
|
83
|
+
it 'rewrites the scheme' do
|
84
|
+
uri = uri_for(adapter: 'sqlite3', database: database)
|
85
|
+
expect(parse(uri).scheme).to eql('sqlite')
|
86
|
+
end
|
87
|
+
|
88
|
+
it 'uses jdbc only on jruby' do
|
89
|
+
uri = uri_for(adapter: 'sqlite3', database: database)
|
90
|
+
expect(uri.starts_with?('jdbc:')).to be(RUBY_ENGINE == 'jruby')
|
91
|
+
end
|
92
|
+
|
93
|
+
it 'expands the path' do
|
94
|
+
uri = uri_for(adapter: 'sqlite3', database: database)
|
95
|
+
expect(parse(uri).path).to eql(root.join(database).to_s)
|
96
|
+
end
|
97
|
+
end
|
98
|
+
end
|
@@ -5,36 +5,76 @@ require 'generators/rom/commands_generator'
|
|
5
5
|
describe ROM::Generators::CommandsGenerator do
|
6
6
|
destination File.expand_path('../../../../tmp', __FILE__)
|
7
7
|
|
8
|
-
before(:
|
8
|
+
before(:each) do
|
9
9
|
prepare_destination
|
10
|
-
run_generator ['users']
|
11
10
|
end
|
12
11
|
|
13
12
|
specify do
|
13
|
+
run_generator ['users']
|
14
|
+
|
15
|
+
default_adapter = ROM.adapters.keys.first
|
16
|
+
|
14
17
|
expect(destination_root).to have_structure {
|
15
18
|
directory 'app' do
|
16
19
|
directory 'commands' do
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
+
directory 'users' do
|
21
|
+
file 'create.rb' do
|
22
|
+
contains <<-CONTENT.strip_heredoc
|
23
|
+
module UserCommands
|
24
|
+
class Create < ROM::Commands::Create[:#{default_adapter}]
|
25
|
+
relation :users
|
26
|
+
register_as :create
|
27
|
+
result :one
|
20
28
|
|
21
|
-
|
22
|
-
|
29
|
+
# define a validator to use
|
30
|
+
# validator UserValidator
|
31
|
+
end
|
23
32
|
end
|
33
|
+
CONTENT
|
34
|
+
end
|
24
35
|
|
25
|
-
|
26
|
-
|
27
|
-
|
36
|
+
file 'update.rb' do
|
37
|
+
contains <<-CONTENT.strip_heredoc
|
38
|
+
module UserCommands
|
39
|
+
class Update < ROM::Commands::Update[:#{default_adapter}]
|
40
|
+
relation :users
|
41
|
+
register_as :update
|
42
|
+
result :one
|
28
43
|
|
29
|
-
|
30
|
-
|
44
|
+
# define a validator to use
|
45
|
+
# validator UserValidator
|
46
|
+
end
|
31
47
|
end
|
48
|
+
CONTENT
|
49
|
+
end
|
32
50
|
|
33
|
-
|
34
|
-
|
51
|
+
file 'delete.rb' do
|
52
|
+
contains <<-CONTENT.strip_heredoc
|
53
|
+
module UserCommands
|
54
|
+
class Delete < ROM::Commands::Delete[:#{default_adapter}]
|
55
|
+
relation :users
|
56
|
+
register_as :delete
|
57
|
+
result :one
|
58
|
+
end
|
59
|
+
end
|
60
|
+
CONTENT
|
61
|
+
end
|
35
62
|
end
|
36
63
|
end
|
37
64
|
end
|
38
65
|
}
|
39
66
|
end
|
67
|
+
|
68
|
+
specify "with given adapter" do
|
69
|
+
run_generator ['users', '--adapter=memory']
|
70
|
+
|
71
|
+
create = File.read(File.join(destination_root, 'app', 'commands', 'users', 'create.rb'))
|
72
|
+
expect(create).to include("class Create < ROM::Commands::Create[:memory]")
|
73
|
+
|
74
|
+
update = File.read(File.join(destination_root, 'app', 'commands', 'users', 'update.rb'))
|
75
|
+
expect(update).to include("class Update < ROM::Commands::Update[:memory]")
|
76
|
+
|
77
|
+
delete = File.read(File.join(destination_root, 'app', 'commands', 'users', 'delete.rb'))
|
78
|
+
expect(delete).to include("class Delete < ROM::Commands::Delete[:memory]")
|
79
|
+
end
|
40
80
|
end
|
@@ -0,0 +1,89 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
require 'generators/rom/form_generator'
|
4
|
+
|
5
|
+
describe ROM::Generators::FormGenerator do
|
6
|
+
destination File.expand_path('../../../../tmp', __FILE__)
|
7
|
+
|
8
|
+
before(:each) do
|
9
|
+
prepare_destination
|
10
|
+
end
|
11
|
+
|
12
|
+
specify "a create form" do
|
13
|
+
run_generator ['users', '--command=create']
|
14
|
+
|
15
|
+
expect(destination_root).to have_structure {
|
16
|
+
directory 'app' do
|
17
|
+
directory 'forms' do
|
18
|
+
file 'new_user_form.rb' do
|
19
|
+
contains <<-CONTENT.strip_heredoc
|
20
|
+
class NewUserForm < ROM::Model::Form
|
21
|
+
commands users: :create
|
22
|
+
|
23
|
+
input do
|
24
|
+
set_model_name 'User'
|
25
|
+
|
26
|
+
# define form input attributes
|
27
|
+
# attribute :name, String
|
28
|
+
|
29
|
+
timestamps
|
30
|
+
end
|
31
|
+
|
32
|
+
validations do
|
33
|
+
relation :users
|
34
|
+
|
35
|
+
# Add form validations
|
36
|
+
# validates :name, presence: true
|
37
|
+
end
|
38
|
+
|
39
|
+
def commit!
|
40
|
+
users.try { users.create.call(params) }
|
41
|
+
end
|
42
|
+
|
43
|
+
end
|
44
|
+
CONTENT
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
}
|
49
|
+
end
|
50
|
+
|
51
|
+
specify "an edit form" do
|
52
|
+
run_generator ['users', '--command=update']
|
53
|
+
|
54
|
+
expect(destination_root).to have_structure {
|
55
|
+
directory 'app' do
|
56
|
+
directory 'forms' do
|
57
|
+
file 'edit_user_form.rb' do
|
58
|
+
contains <<-CONTENT.strip_heredoc
|
59
|
+
class EditUserForm < ROM::Model::Form
|
60
|
+
commands users: :update
|
61
|
+
|
62
|
+
input do
|
63
|
+
set_model_name 'User'
|
64
|
+
|
65
|
+
# define form input attributes
|
66
|
+
# attribute :name, String
|
67
|
+
|
68
|
+
timestamps :updated_at
|
69
|
+
end
|
70
|
+
|
71
|
+
validations do
|
72
|
+
relation :users
|
73
|
+
|
74
|
+
# Add form validations
|
75
|
+
# validates :name, presence: true
|
76
|
+
end
|
77
|
+
|
78
|
+
def commit!
|
79
|
+
users.try { users.update.by_id(id).set(params) }
|
80
|
+
end
|
81
|
+
|
82
|
+
end
|
83
|
+
CONTENT
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|
87
|
+
}
|
88
|
+
end
|
89
|
+
end
|