rom-rails 0.3.0.beta1 → 0.3.0.rc1

Sign up to get free protection for your applications and to get access to all the features.
@@ -7,8 +7,8 @@ module ROM
7
7
  # @example
8
8
  #
9
9
  #
10
- # class UserParams
11
- # include ROM::Model::Params
10
+ # class UserAttributes
11
+ # include ROM::Model::Attributes
12
12
  #
13
13
  # attribute :name
14
14
  #
@@ -19,53 +19,100 @@ module ROM
19
19
  # include ROM::Model::Validator
20
20
  # end
21
21
  #
22
- # params = UserParams.new(name: '')
23
- # UserValidator.call(params) # raises ValidationError
22
+ # attrs = UserAttributes.new(name: '')
23
+ # UserValidator.call(attrs) # raises ValidationError
24
24
  #
25
25
  # @api public
26
26
  module Validator
27
+ # Inclusion hook that extends a class with required interfaces
28
+ #
29
+ # @api private
27
30
  def self.included(base)
28
31
  base.class_eval do
29
32
  extend ClassMethods
30
33
  include ActiveModel::Validations
31
- include Equalizer.new(:params, :errors)
34
+ include Equalizer.new(:attributes, :errors)
32
35
  end
33
36
  end
34
37
 
35
- attr_reader :params
36
- delegate :model_name, to: :params
38
+ # @return [Model::Attributes]
39
+ #
40
+ # @api private
41
+ attr_reader :attributes
37
42
 
38
- def initialize(params)
39
- @params = params
43
+ delegate :model_name, to: :attributes
44
+
45
+ # @api private
46
+ def initialize(attributes)
47
+ @attributes = attributes
40
48
  end
41
49
 
50
+ # @return [Model::Attributes]
51
+ #
52
+ # @api public
42
53
  def to_model
43
- params
54
+ attributes
44
55
  end
45
56
 
57
+ # Trigger validations and return attributes on success
58
+ #
59
+ # @raises ValidationError
60
+ #
61
+ # @return [Model::Attributes]
62
+ #
63
+ # @api public
46
64
  def call
47
65
  raise ValidationError, errors unless valid?
48
- params
66
+ attributes
49
67
  end
50
68
 
51
69
  private
52
70
 
71
+ # This is needed for ActiveModel::Validations to work properly
72
+ # as it expects the object to provide attribute values. Meh.
73
+ #
74
+ # @api private
53
75
  def method_missing(name)
54
- params[name]
76
+ attributes[name]
55
77
  end
56
78
 
57
79
  module ClassMethods
80
+ # Set relation name for a validator
81
+ #
82
+ # This is needed for validators that require database access
83
+ #
84
+ # @example
85
+ #
86
+ # class UserValidator
87
+ # include ROM::Model::Validator
88
+ #
89
+ # relation :users
90
+ #
91
+ # validates :name, uniqueness: true
92
+ # end
93
+ #
94
+ # @return [Symbol]
95
+ #
96
+ # @api public
58
97
  def relation(name = nil)
59
98
  @relation = name if name
60
99
  @relation
61
100
  end
62
101
 
102
+ # FIXME: this looks like not needed
63
103
  def model_name
64
- params.model_name
104
+ attributes.model_name
65
105
  end
66
106
 
67
- def call(params)
68
- validator = new(params)
107
+ # Trigger validation for specific attributes
108
+ #
109
+ # @param [Model::Attributes] attributes The attributes for validation
110
+ #
111
+ # @raises [ValidationError]
112
+ #
113
+ # @return [Model::Attributes]
114
+ def call(attributes)
115
+ validator = new(attributes)
69
116
  validator.call
70
117
  end
71
118
  end
@@ -3,33 +3,69 @@ require 'active_model/validator'
3
3
  module ROM
4
4
  module Model
5
5
  module Validator
6
+ # Uniqueness validation
7
+ #
8
+ # @api public
6
9
  class UniquenessValidator < ActiveModel::EachValidator
7
- attr_reader :klass, :message
10
+ # Relation validator class
11
+ #
12
+ # @api private
13
+ attr_reader :klass
8
14
 
15
+ # error message
16
+ #
17
+ # @return [String, Symbol]
18
+ #
19
+ # @api private
20
+ attr_reader :message
21
+
22
+ # @api private
9
23
  def initialize(options)
10
24
  super
11
25
  @klass = options.fetch(:class)
12
26
  @message = options.fetch(:message) { :taken }
13
27
  end
14
28
 
29
+ # Hook called by ActiveModel internally
30
+ #
31
+ # @api private
15
32
  def validate_each(validator, name, value)
16
33
  validator.errors.add(name, message) unless unique?(name, value)
17
34
  end
18
35
 
19
36
  private
20
37
 
38
+ # Get relation object from the rom env
39
+ #
40
+ # @api private
21
41
  def relation
22
42
  rom.relations[relation_name]
23
43
  end
24
44
 
45
+ # Relation name defined on the validator class
46
+ #
47
+ # @api private
25
48
  def relation_name
26
49
  klass.relation
27
50
  end
28
51
 
52
+ # Shortcut to access global rom env
53
+ #
54
+ # @return [ROM::Env]
55
+ #
56
+ # @api private
29
57
  def rom
30
58
  ROM.env
31
59
  end
32
60
 
61
+ # Ask relation if a given attribute value is unique
62
+ #
63
+ # This uses `Relation#unique?` interface that not all adapters can
64
+ # implement.
65
+ #
66
+ # @return [TrueClass,FalseClass]
67
+ #
68
+ # @api private
33
69
  def unique?(name, value)
34
70
  relation.unique?(name => value)
35
71
  end
@@ -1,5 +1,5 @@
1
1
  module ROM
2
2
  module Rails
3
- VERSION = "0.3.0.beta1".freeze
3
+ VERSION = "0.3.0.rc1".freeze
4
4
  end
5
5
  end
data/rom-rails.gemspec CHANGED
@@ -17,10 +17,10 @@ Gem::Specification.new do |spec|
17
17
  spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
18
18
  spec.require_paths = ["lib"]
19
19
 
20
- spec.add_runtime_dependency 'rom', '~> 0.6.0.beta1'
20
+ spec.add_runtime_dependency 'rom', '~> 0.6.0.rc1'
21
21
  spec.add_runtime_dependency 'addressable', '~> 2.3'
22
22
  spec.add_runtime_dependency 'charlatan', '~> 0.1'
23
- spec.add_runtime_dependency 'virtus', '~> 1.0', '>= 1.0.4'
23
+ spec.add_runtime_dependency 'virtus', '~> 1.0', '>= 1.0.5'
24
24
  spec.add_runtime_dependency 'railties', ['>= 3.0', '< 5.0']
25
25
 
26
26
  spec.add_development_dependency "bundler"
@@ -3,11 +3,14 @@ class UsersController < ApplicationController
3
3
  head :bad_request
4
4
  end
5
5
 
6
- relation 'users.index', only: :index
7
- relation 'users.by_name', only: :search, requires: :name
8
-
9
6
  def index
10
- render
7
+ render :index, locals: { users: rom.relation(:users).as(:users) }
8
+ end
9
+
10
+ def search
11
+ render :index, locals: {
12
+ users: rom.relation(:users).as(:users).by_name(params[:name])
13
+ }
11
14
  end
12
15
 
13
16
  def new
@@ -40,10 +43,6 @@ class UsersController < ApplicationController
40
43
  end
41
44
  end
42
45
 
43
- def search
44
- render :index
45
- end
46
-
47
46
  def ping
48
47
  head :ok
49
48
  end
@@ -1,9 +1,9 @@
1
1
  class NewUserForm < UserForm
2
2
  commands users: :create
3
3
 
4
- params.timestamps(:created_at)
4
+ attributes.timestamps(:created_at)
5
5
 
6
6
  def commit!
7
- users.try { users.create.call(params) }
7
+ users.try { users.create.call(attributes) }
8
8
  end
9
9
  end
@@ -1,9 +1,9 @@
1
1
  class UpdateUserForm < UserForm
2
2
  commands users: :update
3
3
 
4
- params.timestamps(:updated_at)
4
+ attributes.timestamps(:updated_at)
5
5
 
6
6
  def commit!
7
- users.try { users.update.by_id(id).set(params) }
7
+ users.try { users.update.by_id(id).set(attributes) }
8
8
  end
9
9
  end
@@ -1,9 +1,9 @@
1
1
  require 'spec_helper'
2
2
 
3
- describe ROM::Model::Params do
4
- let(:params) do
3
+ describe ROM::Model::Attributes do
4
+ let(:attributes) do
5
5
  Class.new do
6
- include ROM::Model::Params
6
+ include ROM::Model::Attributes
7
7
 
8
8
  attribute :name, String
9
9
 
@@ -13,32 +13,32 @@ describe ROM::Model::Params do
13
13
 
14
14
  describe '.timestamps' do
15
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)
16
+ expect(attributes.new.created_at).to be_a(DateTime)
17
+ expect(attributes.new.updated_at).to be_a(DateTime)
18
18
  end
19
19
 
20
20
  context 'passing in arbritrary names' do
21
21
  it 'excludes :created_at when passing in :updated_at' do
22
- params = Class.new {
23
- include ROM::Model::Params
22
+ attributes = Class.new {
23
+ include ROM::Model::Attributes
24
24
 
25
25
  timestamps(:updated_at)
26
26
  }
27
27
 
28
- model = params.new
28
+ model = attributes.new
29
29
 
30
30
  expect(model).not_to respond_to(:created_at)
31
31
  expect(model).to respond_to(:updated_at)
32
32
  end
33
33
 
34
34
  it 'accepts multiple timestamp attribute names' do
35
- params = Class.new {
36
- include ROM::Model::Params
35
+ attributes = Class.new {
36
+ include ROM::Model::Attributes
37
37
 
38
38
  timestamps(:published_at, :revised_at)
39
39
  }
40
40
 
41
- model = params.new
41
+ model = attributes.new
42
42
 
43
43
  expect(model).to respond_to(:published_at)
44
44
  expect(model).to respond_to(:revised_at)
@@ -3,7 +3,7 @@ require 'spec_helper'
3
3
  describe 'User model mapping' do
4
4
  let(:rom) { ROM.env }
5
5
 
6
- let(:users) { rom.read(:users) }
6
+ let(:users) { rom.relation(:users).as(:users) }
7
7
 
8
8
  before do
9
9
  rom.relations.users.insert(name: 'Piotr', email: 'piotr@test.com')
@@ -37,7 +37,7 @@ describe ROM::Generators::FormGenerator do
37
37
  end
38
38
 
39
39
  def commit!
40
- users.try { users.create.call(params) }
40
+ users.try { users.create.call(attributes) }
41
41
  end
42
42
 
43
43
  end
@@ -76,7 +76,7 @@ describe ROM::Generators::FormGenerator do
76
76
  end
77
77
 
78
78
  def commit!
79
- users.try { users.update.by_id(id).set(params) }
79
+ users.try { users.update.by_id(id).set(attributes) }
80
80
  end
81
81
 
82
82
  end
@@ -17,8 +17,8 @@ describe ROM::Generators::MapperGenerator do
17
17
  file 'user_mapper.rb' do
18
18
  contains <<-CONTENT.strip_heredoc
19
19
  class UserMapper < ROM::Mapper
20
- # relation :users
21
- #
20
+ relation :users
21
+
22
22
  # specify model and attributes ie
23
23
  #
24
24
  # model User
@@ -25,17 +25,21 @@ describe 'Form' do
25
25
 
26
26
  describe '.build' do
27
27
  it 'rejects blank strings from params' do
28
- input = {
29
- 'name' => 'Jane',
30
- 'hash' => { 'one' => '', 'two' => 2 },
31
- 'array' => [{ 'three' => '', 'four' => 4 }, 5]
32
- }
28
+ input = { 'name' => '' }
33
29
 
34
30
  form_object = form.build(input)
35
31
 
36
- expect(form_object.params).to eql(
37
- name: 'Jane', hash: { two: 2 }, array: [{ four: 4 }, 5]
38
- )
32
+ expect(form_object.attributes.to_h).to eql(email: nil)
33
+ end
34
+
35
+ it 'exposes param values' do
36
+ params = { 'email' => 'jane@doe.org' }
37
+ form_object = form.build(params)
38
+ expect(form_object.email).to eql('jane@doe.org')
39
+
40
+ params = { email: 'jane@doe.org' }
41
+ form_object = form.build(params)
42
+ expect(form_object.email).to eql('jane@doe.org')
39
43
  end
40
44
  end
41
45
 
@@ -48,7 +52,7 @@ describe 'Form' do
48
52
  validations { validates :name, presence: true }
49
53
 
50
54
  def commit!
51
- users.try { users.create.call(params) }
55
+ users.try { users.create.call(attributes) }
52
56
  end
53
57
  }
54
58
 
@@ -94,16 +98,16 @@ describe 'Form' do
94
98
  end
95
99
 
96
100
  describe '.model_name' do
97
- it 'delegates to Params.model_name' do
98
- expect(form.model_name).to be(form.params.model_name)
101
+ it 'delegates to Attributes.model_name' do
102
+ expect(form.model_name).to be(form.attributes.model_name)
99
103
  end
100
104
  end
101
105
 
102
106
  describe 'input DSL' do
103
107
  it 'defines params handler' do
104
- expect(form.const_defined?(:Params)).to be(true)
105
- expect(form.params.attribute_set.map(&:name)).to eql([:email])
106
- expect(form.params.model_name).to eql('User')
108
+ expect(form.const_defined?(:Attributes)).to be(true)
109
+ expect(form.attributes.attribute_set.map(&:name)).to eql([:email])
110
+ expect(form.attributes.model_name).to eql('User')
107
111
  end
108
112
 
109
113
  it 'defines a model' do
@@ -278,8 +282,8 @@ describe 'Form' do
278
282
  end
279
283
 
280
284
  it 'copies input' do
281
- expect(child_form.params.attribute_set[:email]).to_not be(nil)
282
- expect(child_form.params).to_not be(form.params)
285
+ expect(child_form.attributes.attribute_set[:email]).to_not be(nil)
286
+ expect(child_form.attributes).to_not be(form.attributes)
283
287
  end
284
288
 
285
289
  it 'copies model' do
@@ -1,11 +1,11 @@
1
1
  require 'spec_helper'
2
2
 
3
3
  describe 'Validation' do
4
- subject(:validator) { user_validator.new(params) }
4
+ subject(:validator) { user_validator.new(attributes) }
5
5
 
6
- let(:user_params) do
6
+ let(:user_attrs) do
7
7
  Class.new {
8
- include ROM::Model::Params
8
+ include ROM::Model::Attributes
9
9
 
10
10
  attribute :name, String
11
11
  attribute :email, String
@@ -28,24 +28,24 @@ describe 'Validation' do
28
28
  end
29
29
 
30
30
  describe '#call' do
31
- let(:params) { {} }
31
+ let(:attributes) { {} }
32
32
 
33
- it 'raises validation error when params are not valid' do
33
+ it 'raises validation error when attributes are not valid' do
34
34
  expect { validator.call }.to raise_error(ROM::Model::ValidationError)
35
35
  end
36
36
  end
37
37
 
38
38
  describe "#validate" do
39
- let(:params) { {} }
39
+ let(:attributes) { {} }
40
40
 
41
- it "sets errors when params are not valid" do
41
+ it "sets errors when attributes are not valid" do
42
42
  validator.validate
43
43
  expect(validator.errors[:name]).to eql(["can't be blank"])
44
44
  end
45
45
  end
46
46
 
47
47
  describe ':presence' do
48
- let(:params) { user_params.new(name: '') }
48
+ let(:attributes) { user_attrs.new(name: '') }
49
49
 
50
50
  it 'sets error messages' do
51
51
  expect(validator).to_not be_valid
@@ -54,7 +54,7 @@ describe 'Validation' do
54
54
  end
55
55
 
56
56
  describe ':uniqueness' do
57
- let(:params) { user_params.new(name: 'Jane', email: 'jane@doe.org') }
57
+ let(:attributes) { user_attrs.new(name: 'Jane', email: 'jane@doe.org') }
58
58
 
59
59
  before do
60
60
  rom.relations.users.insert(name: 'Jane', email: 'jane@doe.org')