rom-rails 0.1.0 → 0.2.0

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 (47) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +59 -0
  3. data/.ruby-version +1 -1
  4. data/.travis.yml +1 -1
  5. data/CHANGELOG.md +13 -0
  6. data/Gemfile +7 -2
  7. data/README.md +29 -18
  8. data/Rakefile +8 -0
  9. data/lib/generators/rom.rb +23 -0
  10. data/lib/generators/rom/commands/templates/commands.rb.erb +15 -0
  11. data/lib/generators/rom/commands_generator.rb +14 -0
  12. data/lib/generators/rom/mapper/templates/mapper.rb.erb +12 -0
  13. data/lib/generators/rom/mapper_generator.rb +14 -0
  14. data/lib/generators/rom/relation/templates/relation.rb.erb +8 -0
  15. data/lib/generators/rom/relation_generator.rb +14 -0
  16. data/lib/rom-rails.rb +5 -4
  17. data/lib/rom/model.rb +95 -0
  18. data/lib/rom/rails/configuration.rb +34 -0
  19. data/lib/rom/rails/controller_extension.rb +34 -1
  20. data/lib/rom/rails/inflections.rb +5 -0
  21. data/lib/rom/rails/railtie.rb +33 -73
  22. data/lib/rom/rails/version.rb +1 -1
  23. data/rom-rails.gemspec +5 -3
  24. data/spec/dummy/app/commands/users.rb +3 -5
  25. data/spec/dummy/app/controllers/users_controller.rb +14 -1
  26. data/spec/dummy/app/mappers/users.rb +1 -3
  27. data/spec/dummy/app/params/user_params.rb +7 -0
  28. data/spec/dummy/app/relations/users.rb +5 -5
  29. data/spec/dummy/app/validators/user_validator.rb +3 -0
  30. data/spec/dummy/config/boot.rb +1 -1
  31. data/spec/dummy/config/environments/development.rb +0 -1
  32. data/spec/dummy/config/environments/production.rb +0 -2
  33. data/spec/dummy/config/environments/test.rb +0 -4
  34. data/spec/dummy/config/routes.rb +2 -0
  35. data/spec/dummy/db/schema.rb +9 -2
  36. data/spec/dummy/spec/controllers/users_controller_spec.rb +29 -0
  37. data/spec/dummy/spec/features/users_spec.rb +11 -2
  38. data/spec/dummy/spec/integration/logger_spec.rb +3 -2
  39. data/spec/dummy/spec/integration/user_commands_spec.rb +21 -0
  40. data/spec/dummy/spec/integration/user_params_spec.rb +33 -0
  41. data/spec/lib/generators/commands_generator_spec.rb +40 -0
  42. data/spec/lib/generators/mapper_generator_spec.rb +37 -0
  43. data/spec/lib/generators/relation_generator_spec.rb +33 -0
  44. data/spec/spec_helper.rb +5 -0
  45. metadata +63 -10
  46. data/lib/rom/rom-rails.rb +0 -8
  47. data/spec/unit/configuration_spec.rb +0 -39
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 57acc5483339020a93cd65499e75ca03dc291fd4
4
- data.tar.gz: bc3013bffa67f101f3c4fadc45406592736d82ca
3
+ metadata.gz: 8841ce1317e0b85ca6e9df4bfcdbc30b0a3a545f
4
+ data.tar.gz: 2f9a18f403fcaf8bda465616937ebfcda0464ec7
5
5
  SHA512:
6
- metadata.gz: 124e3beef32513ae8c52f06474268e38b8ffc725b8bc72a016aaa7d674d35d4392795fd32122cf33a5fed613f6fb988eeaa822bbe4d5c44731a2d970acfdbd97
7
- data.tar.gz: bce26a4fe2fa76fd0e58e57e66f64d5e5a39c90e1e6adce34ed5b8ae45ca4a813d50473df8d59a5ddf45bd9fddb956a5c0d5152def8a641bfcaaecb02a273baa
6
+ metadata.gz: bac7c987bad0abc06d290b68ebb7078330febd35ff76571cd0e4f240c89c4a494e67dcc519e860b2bae7552f6876691eecb641186b99c08178745da43e881293
7
+ data.tar.gz: 2d57f131b6515a8176c05fc7574b82aee3e8129385b026c8fa0accf296637427d5ae3e882336867eca2f84d379643e4661afb3d4ff94358e03a85b9a7d946d73
@@ -0,0 +1,59 @@
1
+ # FIXME: Lower by refactoring biggest offenders
2
+ Metrics/AbcSize:
3
+ Max: 26
4
+
5
+ # FIXME: Lower by refactoring biggest offenders
6
+ Metrics/CyclomaticComplexity:
7
+ Max: 8
8
+
9
+ # FIXME: No clue how to fix that one line…
10
+ Metrics/LineLength:
11
+ Exclude:
12
+ - lib/rom/rails/configuration.rb
13
+
14
+ # FIXME: Lower by refactoring biggest offenders
15
+ Metrics/MethodLength:
16
+ Max: 22
17
+
18
+ # FIXME: Lower by refactoring biggest offenders
19
+ Metrics/PerceivedComplexity:
20
+ Max: 10
21
+
22
+ # Don’t check temp and Rails-generated files
23
+ AllCops:
24
+ Exclude:
25
+ - spec/dummy/Rakefile
26
+ - spec/dummy/config/**/*
27
+ - spec/dummy/db/schema.rb
28
+ - spec/dummy/db/seeds.rb
29
+ - tmp/**/*
30
+
31
+ # Documentation checked by Inch CI
32
+ Style/Documentation:
33
+ Enabled: false
34
+
35
+ # This is a shim file for those who require 'rom-mongo'
36
+ Style/FileName:
37
+ Exclude:
38
+ - lib/rom-rails.rb
39
+
40
+ # Early returns have their vices
41
+ Style/GuardClause:
42
+ Enabled: false
43
+
44
+ # Model::Validator uses Model::ValidationError for this
45
+ Style/RaiseArgs:
46
+ Exclude:
47
+ - lib/rom/model.rb
48
+
49
+ # Even a single escaped slash can be confusing
50
+ Style/RegexpLiteral:
51
+ MaxSlashes: 0
52
+
53
+ # Don’t introduce semantic fail/raise distinction
54
+ Style/SignalException:
55
+ EnforcedStyle: only_raise
56
+
57
+ # Accept both single and double quotes
58
+ Style/StringLiterals:
59
+ Enabled: false
@@ -1 +1 @@
1
- 2.1.4
1
+ 2.1
@@ -6,13 +6,13 @@ script: "RAILS_ENV=test rake app:db:schema:load app:spec"
6
6
  rvm:
7
7
  - 2.0
8
8
  - 2.1
9
+ - 2.2
9
10
  - rbx-2
10
11
  - jruby
11
12
  - ruby-head
12
13
  matrix:
13
14
  allow_failures:
14
15
  - rvm: ruby-head
15
- - rvm: jruby
16
16
  notifications:
17
17
  webhooks:
18
18
  urls:
@@ -1,3 +1,16 @@
1
+ ## v0.2.0 2014-12-31
2
+
3
+ ### Added
4
+
5
+ * Generators for relations, mappers and commands (solnic)
6
+ * Support for Spring and reload in development mode (solnic)
7
+
8
+ ### Fixed
9
+
10
+ * Setup will be skipped when there are missing elements in the registries (solnic)
11
+
12
+ [Compare v0.1.0...v0.2.0](https://github.com/rom-rb/rom-rails/compare/v0.1.0...v0.2.0)
13
+
1
14
  ## v0.1.0 2014-12-06
2
15
 
3
16
  ### Added
data/Gemfile CHANGED
@@ -2,10 +2,14 @@ source 'https://rubygems.org'
2
2
 
3
3
  gemspec
4
4
 
5
- gem 'rails', '4.1.7'
5
+ gem 'rails', '4.2.0'
6
6
 
7
7
  gem 'sqlite3', platforms: [:mri, :rbx]
8
- gem 'jdbc-sqlite3', platforms: :jruby
8
+
9
+ platforms :jruby do
10
+ gem 'jdbc-sqlite3'
11
+ gem 'activerecord-jdbc-adapter'
12
+ end
9
13
 
10
14
  group :test do
11
15
  gem 'rom', github: 'rom-rb/rom', branch: 'master'
@@ -14,4 +18,5 @@ group :test do
14
18
  gem 'codeclimate-test-reporter', require: nil
15
19
  gem 'database_cleaner'
16
20
  gem 'capybara'
21
+ gem 'generator_spec'
17
22
  end
data/README.md CHANGED
@@ -1,10 +1,3 @@
1
- [![Gem Version](https://badge.fury.io/rb/rom-rails.svg)][gem]
2
- [![Build Status](https://travis-ci.org/rom-rb/rom-rails.svg?branch=master)][travis]
3
- [![Dependency Status](https://gemnasium.com/rom-rb/rom-rails.png)][gemnasium]
4
- [![Code Climate](https://codeclimate.com/github/rom-rb/rom-rails/badges/gpa.svg)][codeclimate]
5
- [![Test Coverage](https://codeclimate.com/github/rom-rb/rom-rails/badges/coverage.svg)][codeclimate]
6
- [![Inline docs](http://inch-ci.org/github/rom-rb/rom-rails.svg?branch=master)][inchpages]
7
-
8
1
  [gem]: https://rubygems.org/gems/rom-rails
9
2
  [travis]: https://travis-ci.org/rom-rb/rom-rails
10
3
  [gemnasium]: https://gemnasium.com/rom-rb/rom-rails
@@ -14,6 +7,13 @@
14
7
 
15
8
  # rom-rails
16
9
 
10
+ [![Gem Version](https://badge.fury.io/rb/rom-rails.svg)][gem]
11
+ [![Build Status](https://travis-ci.org/rom-rb/rom-rails.svg?branch=master)][travis]
12
+ [![Dependency Status](https://gemnasium.com/rom-rb/rom-rails.png)][gemnasium]
13
+ [![Code Climate](https://codeclimate.com/github/rom-rb/rom-rails/badges/gpa.svg)][codeclimate]
14
+ [![Test Coverage](https://codeclimate.com/github/rom-rb/rom-rails/badges/coverage.svg)][codeclimate]
15
+ [![Inline docs](http://inch-ci.org/github/rom-rb/rom-rails.svg?branch=master)][inchpages]
16
+
17
17
  Rails integration for [Ruby Object Mapper](https://github.com/rom-rb/rom).
18
18
 
19
19
  ## Installation and setup
@@ -40,22 +40,33 @@ rom's setup object is available via `Rails.application.config.rom.setup`.
40
40
 
41
41
  ## Relations in controllers
42
42
 
43
- Currently the railtie simply adds `#rom` method to your controllers which returns
44
- the whole environment. This is **a temporary solution** which is not meant to be final.
43
+ The recommended way of using relations in controllers is to specify which relations
44
+ are needed for particular actions using a DSL provided by the railtie:
45
+
46
+ ``` ruby
47
+ class UsersController < ApplicationController
48
+ relation 'users.index', only: :index
49
+ relation 'users.by_name', only: :search, requires: :name
50
+
51
+ def index
52
+ render
53
+ end
54
+
55
+ def search
56
+ render :index
57
+ end
58
+ end
59
+ ```
45
60
 
46
- Eventually ROM will expose relations to the controller layer (thus view layer too)
47
- that are already loaded into memory and **there will be no database interactions**
48
- taking place in those layers. This means that effectively database **query interface
49
- will not be available in controllers, views, helpers or anywhere outside of the
50
- relation definitions**.
61
+ By doing this actions will have access to `users` which is also set as a helper
62
+ method making it available in the views.
51
63
 
52
- This means your Rails application will work with arrays of domain objects rather
53
- than ad-hoc database queries scattered across your entire codebase and there will
54
- be *a single place* where you define all the relations and object mapping.
64
+ This means **no database interaction will take place in the views or helpers**
65
+ as ROM materializes relations when "injecting" them into controller actions.
55
66
 
56
67
  ## Status
57
68
 
58
- This project is still in alpha state. For examples of usage please take a look
69
+ This project is still in beta state. For examples of usage please take a look
59
70
  at `spec/dummy` app.
60
71
 
61
72
  Proper documentation will be added once the interface is stable.
data/Rakefile CHANGED
@@ -1,4 +1,12 @@
1
1
  require 'bundler/setup'
2
+ require 'rubocop/rake_task'
3
+
4
+ task default: %w(app:db:schema:load app:spec rubocop)
2
5
 
3
6
  APP_RAKEFILE = File.expand_path("../spec/dummy/Rakefile", __FILE__)
4
7
  load 'rails/tasks/engine.rake'
8
+
9
+ RuboCop::RakeTask.new do |task|
10
+ task.options << '--display-cop-names'
11
+ task.options << '--rails'
12
+ end
@@ -0,0 +1,23 @@
1
+ require 'rails/generators/named_base'
2
+ require 'rom/rails/inflections'
3
+
4
+ module ROM
5
+ module Generators
6
+ class Base < ::Rails::Generators::NamedBase
7
+ def self.base_name
8
+ 'rom'
9
+ end
10
+
11
+ def self.namespace
12
+ "rom:#{generator_name}"
13
+ end
14
+
15
+ def self.source_root
16
+ File.expand_path(
17
+ "../#{base_name}/#{generator_name}/templates",
18
+ __FILE__
19
+ )
20
+ end
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,15 @@
1
+ ROM.commands(:<%= class_name.underscore %>) do
2
+
3
+ define(:create) do
4
+ result :one
5
+ end
6
+
7
+ define(:update) do
8
+ result :one
9
+ end
10
+
11
+ define(:delete) do
12
+ result :one
13
+ end
14
+
15
+ end
@@ -0,0 +1,14 @@
1
+ require 'generators/rom'
2
+
3
+ module ROM
4
+ module Generators
5
+ class CommandsGenerator < Base
6
+ def create_commands_file
7
+ template(
8
+ 'commands.rb.erb',
9
+ File.join('app', 'commands', "#{file_name}.rb")
10
+ )
11
+ end
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,12 @@
1
+ ROM.mappers do
2
+
3
+ define(:<%= class_name.underscore %>) do
4
+ # specify model and attributes ie
5
+ #
6
+ # model <%= class_name.classify %>
7
+ #
8
+ # attribute :name
9
+ # attribute :email
10
+ end
11
+
12
+ end
@@ -0,0 +1,14 @@
1
+ require 'generators/rom'
2
+
3
+ module ROM
4
+ module Generators
5
+ class MapperGenerator < Base
6
+ def create_mapper_file
7
+ template(
8
+ 'mapper.rb.erb',
9
+ File.join('app', 'mappers', "#{file_name}.rb")
10
+ )
11
+ end
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,8 @@
1
+ ROM.relation(:<%= class_name.underscore %>) do
2
+ # define your methods here ie:
3
+ #
4
+ # def all
5
+ # select(:id, :name).order(:id)
6
+ # end
7
+ #
8
+ end
@@ -0,0 +1,14 @@
1
+ require 'generators/rom'
2
+
3
+ module ROM
4
+ module Generators
5
+ class RelationGenerator < Base
6
+ def create_relation_file
7
+ template(
8
+ 'relation.rb.erb',
9
+ File.join('app', 'relations', "#{file_name}.rb")
10
+ )
11
+ end
12
+ end
13
+ end
14
+ end
@@ -1,8 +1,9 @@
1
- module Rom
1
+ module ROM
2
2
  module Rails
3
3
  end
4
4
  end
5
5
 
6
- require "rom/rails/version"
7
- require "rom/rails/railtie"
8
- require "rom/rails/controller_extension"
6
+ require 'rom'
7
+ require 'rom/rails/version'
8
+ require 'rom/rails/railtie'
9
+ require 'rom/model'
@@ -0,0 +1,95 @@
1
+ require 'virtus'
2
+ require 'active_model'
3
+
4
+ module ROM
5
+ module Model
6
+ class ValidationError < CommandError
7
+ attr_reader :params, :messages
8
+
9
+ def initialize(params)
10
+ @params = params
11
+ @messages = params.errors
12
+ end
13
+ end
14
+
15
+ # Mixin for validatable and coercible parameters
16
+ #
17
+ # @example
18
+ #
19
+ # class UserParams
20
+ # include ROM::Model::Params
21
+ #
22
+ # attribute :email, String
23
+ # attribute :age, Integer
24
+ #
25
+ # validates :email, :age, presence: true
26
+ # end
27
+ #
28
+ # user_params = UserParams.new(email: '', age: '18')
29
+ #
30
+ # user_params.email # => ''
31
+ # user_params.age # => 18
32
+ #
33
+ # user_params.valid? # => false
34
+ # user_params.errors # => #<ActiveModel::Errors:0x007fd2423fadb0 ...>
35
+ #
36
+ # @api public
37
+ module Params
38
+ def self.included(base)
39
+ base.class_eval do
40
+ include Virtus.model
41
+ include ActiveModel::Validations
42
+ include ActiveModel::Conversion
43
+ end
44
+ base.extend(ClassMethods)
45
+ end
46
+
47
+ module ClassMethods
48
+ def param_key(name)
49
+ class_eval <<-RUBY
50
+ def self.model_name
51
+ @model_name ||= ActiveModel::Name.new(self, nil, #{name.to_s.inspect})
52
+ end
53
+ RUBY
54
+ end
55
+
56
+ def [](input)
57
+ new(input)
58
+ end
59
+ end
60
+ end
61
+
62
+ # Mixin for ROM-compliant validator objects
63
+ #
64
+ # @example
65
+ #
66
+ #
67
+ # class UserParams
68
+ # include ROM::Model::Params
69
+ #
70
+ # attribute :name
71
+ #
72
+ # validates :name, presence: true
73
+ # end
74
+ #
75
+ # class UserValidator
76
+ # include ROM::Model::Validator
77
+ # end
78
+ #
79
+ # params = UserParams.new(name: '')
80
+ # UserValidator.call(params) # raises ValidationError
81
+ #
82
+ # @api public
83
+ module Validator
84
+ def self.included(base)
85
+ base.extend(ClassMethods)
86
+ end
87
+
88
+ module ClassMethods
89
+ def call(params)
90
+ raise ValidationError.new(params) unless params.valid?
91
+ end
92
+ end
93
+ end
94
+ end
95
+ end
@@ -0,0 +1,34 @@
1
+ module ROM
2
+ module Rails
3
+ class Configuration
4
+ attr_reader :config, :setup, :env
5
+
6
+ def self.build(app)
7
+ config = app.config.database_configuration[::Rails.env].
8
+ symbolize_keys.update(root: app.config.root)
9
+
10
+ new(ROM::Config.build(config))
11
+ end
12
+
13
+ def initialize(config)
14
+ @config = config
15
+ end
16
+
17
+ def setup!
18
+ @setup = ROM.setup(@config.symbolize_keys)
19
+ end
20
+
21
+ def load!
22
+ Railtie.load_all
23
+ end
24
+
25
+ def finalize!
26
+ # rescuing fixes the chicken-egg problem where we have a relation
27
+ # defined but the table doesn't exist yet
28
+ @env = ROM.finalize.env
29
+ rescue Registry::ElementNotFoundError => e
30
+ warn "Skipping ROM setup => #{e.message}"
31
+ end
32
+ end
33
+ end
34
+ end