yuba 0.0.1.pre → 0.0.5

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
- SHA1:
3
- metadata.gz: 065c02ba0b6ba7a96764c3557e3f3abad4e2252d
4
- data.tar.gz: 13c440a52f8042fcd001d6d1305e233184c8aca2
2
+ SHA256:
3
+ metadata.gz: 7d13a7bddc245ba124ce105b6827afb261d6268a417809a6bc7ec04e70cff0b9
4
+ data.tar.gz: c4769bdc11c239e2c99d848ab99f9b13309c5f6c4064b53b52b4087c025eeaa8
5
5
  SHA512:
6
- metadata.gz: 107fbf7894edb031119725bd8f9844d78e52dbc3fc9f763cc0b60a244f50868b45949b2ffec47847e92a780598ee5af07e0a835adbcc15e339868ded43b275b8
7
- data.tar.gz: c9494157393285ba6b41d231ef56338411c890b96711010278053d6fdb00d71a6f4626ff1b564c1ba6bcecfebb3ea89c14e1f943dbdf83d12298ba5dddb33a10
6
+ metadata.gz: 8337d0d4addebc3bd44412fd23d4433ebb6f17d53db5e63dcfe666b4dda6351de39450f9d48ef7fc225d62871b52d90082cefac7e6b705b38b185c1c2e9c7733
7
+ data.tar.gz: 77447d91b1a2d68dd7cbf44055188d5e2bb6ac45b3b8e17af5101b0ce04952f7c4accb25f394eca3e8ba4a5b51690faba9978c45619a42603a265a19acd3c040
data/README.md CHANGED
@@ -1,6 +1,13 @@
1
1
  # Yuba
2
2
 
3
- This gem is now under construction. It doesn't work now.
3
+ [![Build Status](https://travis-ci.org/willnet/yuba.svg?branch=master)](https://travis-ci.org/willnet/yuba)
4
+ [![Gem Version](https://badge.fury.io/rb/yuba.svg)](https://badge.fury.io/rb/yuba)
5
+
6
+ ## warning
7
+
8
+ Version of this gem is now 0.0.x. It works but there must be occasional breaking changes to the API.
9
+
10
+ ## Summary
4
11
 
5
12
  Yuba add new layers to rails.
6
13
 
@@ -8,11 +15,12 @@ Yuba add new layers to rails.
8
15
  - Form
9
16
  - ViewModel
10
17
 
11
- ## Usage
18
+ It is convenient to use them in combination, but you can use them even by themselves.
12
19
 
13
- How to use my plugin.
20
+ If you have difficulties with large rails application, Yuba help you.
14
21
 
15
22
  ## Installation
23
+
16
24
  Add this line to your application's Gemfile:
17
25
 
18
26
  ```ruby
@@ -20,17 +28,217 @@ gem 'yuba'
20
28
  ```
21
29
 
22
30
  And then execute:
31
+
23
32
  ```bash
24
- $ bundle
33
+ $ bundle install
25
34
  ```
26
35
 
27
- Or install it yourself as:
28
- ```bash
29
- $ gem install yuba
36
+ ## Support
37
+
38
+ - Rails 4.2+
39
+ - Ruby 2.2+
40
+
41
+ ## ViewModel
42
+
43
+ ViewModel is useful when there are many instance variables in controller.
44
+
45
+ ```ruby
46
+ class PostViewModel < Yuba::ViewModel
47
+ property :post
48
+ property :author, public: true
49
+ property :other, optional: true
50
+
51
+ def title
52
+ post.title
53
+ end
54
+
55
+ def body
56
+ post.body
57
+ end
58
+ end
59
+
60
+ Post = Struct.new(:title, :body)
61
+ post = Post.new('hello', 'world')
62
+
63
+ view_model = PostViewModel.new(post: post, author: 'willnet')
64
+ view.title #=> 'hello'
65
+ view.body #=> 'world'
66
+ view.author #=> 'willnet'
67
+ view.post #=> NoMethodError
68
+ ```
69
+
70
+ ### property
71
+
72
+ `.property` method register property to the class.
73
+
74
+ Those registered by property need to be passed as arguments to the `initialize` except when `optional: true` is attached. You get ArgumentError if you don't pass `property` to `initialize`.
75
+
76
+ Property is default to private. This means you can use it in internal the instance. If you want to use it as public, use `public: true` option.
77
+
78
+ ### Auto Assign
79
+
80
+ You can use ViewModel in a controller like following
81
+
82
+ ```ruby
83
+ class PostsController < ApplicationController
84
+ def show
85
+ @view_model = PostViewModel.new(post: post, author: 'willnet')
86
+ end
87
+ end
88
+ ```
89
+
90
+ In view template, if you want to access post and author, you have to use `@view_model` instance variable like `@view_model.post.title`. if it feels troublesome, you can write like following
91
+
92
+ ```ruby
93
+ class PostsController < ApplicationController
94
+ def show
95
+ view_model = PostViewModel.new(post: post, author: 'willnet')
96
+ render view_model: view_model
97
+ end
98
+ end
99
+ ```
100
+
101
+ view_model option of render takes ViewModel, which get it's public methods (include public property) and assign them to instance variables in view template. So you can write `<%= @post.title %>` instead of `<%= @view_model.post.title %>`
102
+
103
+ ## Service
104
+
105
+ Service is useful when controller has many application logic.
106
+
107
+ ```ruby
108
+ class PostController < ApplicationController
109
+ def new
110
+ @post = CreatePostService.call(user: current_user).post
111
+ end
112
+
113
+ def create
114
+ service = CreatePostService.call(user: current_user, params: params)
115
+
116
+ if service.success?
117
+ redirect_to root_path
118
+ else
119
+ @post = service.post
120
+ render :new
121
+ end
122
+ end
123
+ end
124
+
125
+ class CreatePostService < Yuba::Service
126
+ property :user, public: true
127
+ property :params, optional: true
128
+
129
+ def call
130
+ if post.save
131
+ notify_to_admin
132
+ else
133
+ fail!
134
+ end
135
+ end
136
+
137
+ def post
138
+ user.posts.build(post_params)
139
+ end
140
+
141
+ private
142
+
143
+ def notify_to_admin
144
+ AdminMailer.notify_create_post(post).deliver_later
145
+ end
146
+
147
+ def post_params
148
+ params.require(:post).permit(:title, :body)
149
+ end
150
+ end
151
+ ```
152
+
153
+ - `.property` method register property to the class like ViewModel.
154
+ - `.call` invokes `#call` after assigning arguments as properties.
155
+ - `#success?` returns `true` if you don't invoke `#fail!`
156
+
157
+ ## Form
158
+
159
+ Form is just wrapper of [reform-rails](https://github.com/trailblazer/reform-rails) for now.
160
+
161
+ You can see documentation [here](http://trailblazer.to/gems/reform/rails.html).
162
+
163
+ ## Combination Sample
164
+
165
+ ```ruby
166
+ class ArtistsController < ApplicationController
167
+ def new
168
+ @view_model = Artist::CreateService.new(params: params).view_model
169
+ end
170
+
171
+ def create
172
+ service = Artist::CreateService.call(params: params)
173
+
174
+ if service.success?
175
+ redirect_to artists_path
176
+ else
177
+ @view_model = service.view_model
178
+ render :new
179
+ end
180
+ end
181
+ end
182
+ ```
183
+
184
+ ```ruby
185
+ class Artist::CreateService < Yuba::Service
186
+ property :params
187
+
188
+ def call
189
+ if form.validate(params)
190
+ form.save
191
+ else
192
+ fail!
193
+ end
194
+ end
195
+
196
+ def view_model
197
+ Artist::CreateViewModel.new(form: form)
198
+ end
199
+
200
+ private
201
+
202
+ def form
203
+ @form ||= ArtistForm.new(Artist.new)
204
+ end
205
+ end
206
+ ```
207
+
208
+ ```ruby
209
+ class ArtistForm < Yuba::Form
210
+ property :name
211
+
212
+ validates :name, presence: true, length: { maximum: 100 }
213
+ end
214
+ ```
215
+
216
+ ```ruby
217
+ class Artist::CreateViewModel < Yuba::ViewModel
218
+ property :form, public: true
219
+ end
220
+ ```
221
+
222
+ ## generators
223
+
224
+ You can use generators.
225
+
226
+ ```
227
+ rails generate yuba:service create_artist
228
+ rails generate yuba:form artist
229
+ rails generate yuba:view_model artist_index
30
230
  ```
31
231
 
32
232
  ## Contributing
33
- Contribution directions go here.
233
+
234
+ You can try to test by doing as following
235
+
236
+ ```
237
+ git clone https://github.com/willnet/yuba.git
238
+ cd yuba
239
+ bundle
240
+ bundle exec rake
241
+ ```
34
242
 
35
243
  ## License
36
244
  The gem is available as open source under the terms of the [MIT License](http://opensource.org/licenses/MIT).
@@ -0,0 +1,9 @@
1
+ module Yuba
2
+ class FormGenerator < ::Rails::Generators::NamedBase
3
+ source_root File.expand_path('../templates', __FILE__)
4
+
5
+ def generate_form
6
+ template 'form.tt', File.join('app/forms', class_path, "#{file_name}_form.rb")
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,4 @@
1
+ <% module_namespacing do -%>
2
+ class <%= class_name %>Form < Yuba::Form
3
+ end
4
+ <% end -%>
@@ -0,0 +1,9 @@
1
+ module Yuba
2
+ class ServiceGenerator < ::Rails::Generators::NamedBase
3
+ source_root File.expand_path('../templates', __FILE__)
4
+
5
+ def generate_service
6
+ template 'service.tt', File.join('app/services', class_path, "#{file_name}_service.rb")
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,6 @@
1
+ <% module_namespacing do -%>
2
+ class <%= class_name %>Service < Yuba::Service
3
+ def call
4
+ end
5
+ end
6
+ <% end -%>
@@ -0,0 +1,4 @@
1
+ <% module_namespacing do -%>
2
+ class <%= class_name %>ViewModel < Yuba::ViewModel
3
+ end
4
+ <% end -%>
@@ -0,0 +1,9 @@
1
+ module Yuba
2
+ class ViewModelGenerator < ::Rails::Generators::NamedBase
3
+ source_root File.expand_path('../templates', __FILE__)
4
+
5
+ def generate_view_model
6
+ template 'view_model.tt', File.join('app/view_models', class_path, "#{file_name}_view_model.rb")
7
+ end
8
+ end
9
+ end
@@ -1,5 +1,12 @@
1
+ require 'reform/rails'
2
+ require 'dry/types'
3
+
1
4
  module Yuba
2
5
  autoload :Form, 'yuba/form'
3
6
  autoload :Service, 'yuba/service'
4
7
  autoload :ViewModel, 'yuba/view_model'
5
8
  end
9
+
10
+ ActiveSupport.on_load(:action_controller) do
11
+ ActionController::Base.include(Yuba::ViewModel::Rendering)
12
+ end
@@ -1,60 +1,15 @@
1
- module Yuba
2
- class Form
3
- autoload :Attribute, 'yuba/form/attribute'
4
- autoload :Attributes, 'yuba/form/attributes'
5
- autoload :Collection, 'yuba/form/collection'
6
-
7
- include ActiveModel::Model
8
- class_attribute :_model_attribute
9
- class_attribute :attributes
1
+ require 'yuba/form/coercion'
2
+ require 'yuba/form/multi_parameter_attributes'
10
3
 
4
+ module Yuba
5
+ class Form < ::Reform::Form
11
6
  class << self
12
- # TODO: reformのようにネストできるようにしたい
13
- def attribute(name, type: 'string', &block)
14
- mod = Module.new do
15
- define_method(name) do
16
- attributes[name.to_s]
17
- end
18
- define_method("#{name}=") do |value|
19
- write_attribute(name.to_s, value, block)
20
- end
21
- end
22
- include mod
23
- end
24
-
25
- def collection(name)
7
+ def inherited(subclass)
8
+ subclass.feature Coercion
9
+ subclass.feature MultiParameterAttributes
10
+ subclass.include Reform::Form::ActiveRecord
11
+ subclass.include Reform::Form::ActiveModel::ModelReflections
26
12
  end
27
-
28
- def model(name)
29
- self._model_attribute = name
30
- end
31
-
32
- def build(**args)
33
- new(**args)
34
- end
35
- end
36
-
37
- def save
38
- valid? && persist
39
- end
40
-
41
- def persist
42
- end
43
-
44
- def model
45
- send(_model_attribute)
46
- end
47
-
48
- def model_name
49
- model&.model_name
50
- end
51
-
52
- private
53
-
54
- def write_attribute(name, value, block)
55
- # TODO: convert value by type of attribute
56
- value = Attributes.new(value, &block) if block
57
- attributes[name] = value
58
13
  end
59
14
  end
60
15
  end
@@ -0,0 +1,36 @@
1
+ require 'dry-types'
2
+
3
+ module Yuba
4
+ class Form < ::Reform::Form
5
+ module Coercion
6
+ module Types
7
+ include Dry::Types.module
8
+ end
9
+
10
+ module ClassMethods
11
+ def property(name, options={}, &block)
12
+ super(name, options, &block).tap do
13
+ break unless options[:type]
14
+ coercing_setter!(name, options[:type])
15
+ end
16
+ end
17
+
18
+ def coercing_setter!(name, type)
19
+ class_name = type.to_s.classify
20
+ type_class = "Yuba::Form::Coercion::Types::Form::#{class_name}".constantize
21
+
22
+ mod = Module.new do
23
+ define_method("#{name}=") do |value|
24
+ super type_class.(value)
25
+ end
26
+ end
27
+ include mod
28
+ end
29
+ end
30
+
31
+ def self.included(includer)
32
+ includer.extend ClassMethods
33
+ end
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,52 @@
1
+ module Yuba::Form::MultiParameterAttributes
2
+ # TODO: implement this with parse_filter, so we don't have to manually walk through the hash, etc.
3
+ class DateTimeParamsFilter
4
+ def call(params)
5
+ params = params.dup # DISCUSS: not sure if that slows down form processing?
6
+ date_attributes = {}
7
+
8
+ params.each do |attribute, value|
9
+ if value.is_a?(Hash)
10
+ params[attribute] = call(value) # TODO: #validate should only handle local form params.
11
+ elsif matches = attribute.match(/^(\w+)\(.i\)$/)
12
+ date_attribute = matches[1]
13
+ date_attributes[date_attribute] = params_to_date(
14
+ params.delete("#{date_attribute}(1i)"),
15
+ params.delete("#{date_attribute}(2i)"),
16
+ params.delete("#{date_attribute}(3i)"),
17
+ params.delete("#{date_attribute}(4i)"),
18
+ params.delete("#{date_attribute}(5i)")
19
+ )
20
+ end
21
+ end
22
+
23
+ date_attributes.each do |attribute, date|
24
+ params[attribute] = date
25
+ end
26
+ params
27
+ end
28
+
29
+ private
30
+ def params_to_date(year, month, day, hour, minute)
31
+ date_fields = [year, month, day].map!(&:to_i)
32
+ time_fields = [hour, minute].map!(&:to_i)
33
+
34
+ if date_fields.any?(&:zero?) || !Date.valid_date?(*date_fields)
35
+ return nil
36
+ end
37
+
38
+ if hour.blank? && minute.blank?
39
+ Date.new(*date_fields)
40
+ else
41
+ args = date_fields + time_fields
42
+ Time.zone ? Time.zone.local(*args) :
43
+ Time.new(*args)
44
+ end
45
+ end
46
+ end
47
+
48
+ # this hooks into the format-specific #deserialize! method.
49
+ def deserialize!(params)
50
+ super DateTimeParamsFilter.new.call(params) # if params.is_a?(Hash) # this currently works for hash, only.
51
+ end
52
+ end
@@ -1,37 +1,70 @@
1
1
  module Yuba
2
2
  class Service
3
+ class_attribute :_properties
4
+ self._properties = {}
5
+
3
6
  class << self
4
7
  def call(**args)
5
- service = new
6
- return_value = args.present? ? service.call(**args) : service.call
7
- if return_value.respond_to?(:success?)
8
- return_value
9
- else
10
- result.success(form: service.form)
11
- end
8
+ service = args.empty? ? new : new(**args)
9
+ service.call
10
+ service
11
+ end
12
+
13
+ def property(name, options = {})
14
+ self._properties = _properties.merge(name.to_sym => options)
12
15
  end
13
16
  end
14
17
 
15
- def build_form(**args)
16
- form_class.build(**args)
18
+ def initialize(**args)
19
+ validate_arguments(args)
20
+ define_accessors(args)
21
+ success
22
+ end
23
+
24
+ def success
25
+ @_success = true
26
+ end
27
+
28
+ def fail!
29
+ @_success = false
17
30
  end
18
31
 
19
- def form_class
20
- Object.const_get(form_class_name)
32
+ def success?
33
+ @_success
21
34
  end
22
35
 
23
- def view_model_class
24
- Object.const_get(form_class_name)
36
+ def failure?
37
+ !@_success
25
38
  end
26
39
 
27
40
  private
28
41
 
29
- def form_class_name
30
- self.class.name.sub(/::.+Service/, 'Form')
42
+ def validate_arguments(args)
43
+ args.each_key do |key|
44
+ if !_properties.has_key?(key.to_sym) && !_properties.dig(key.to_sym, :optional)
45
+ raise ArgumentError, "missing 'property :#{key}' in #{self.class.name} class"
46
+ end
47
+ end
48
+
49
+ required_keys = _required_properties.keys
50
+ missing_keys = required_keys - args.keys
51
+ unless missing_keys.empty?
52
+ raise ArgumentError, "missing required arguments: #{missing_keys.join(',')}"
53
+ end
54
+ end
55
+
56
+ def define_accessors(args)
57
+ args.each do |key, value|
58
+ public_method = _properties[key.to_sym][:public]
59
+ define_singleton_method key do
60
+ value
61
+ end
62
+ self.singleton_class.class_eval { private key.to_sym } unless public_method
63
+ end
31
64
  end
32
65
 
33
- def view_model_class_name
34
- self.class.name.sub(/Service\z/, 'ViewModel')
66
+ def _required_properties
67
+ _properties.reject { |_, value| value[:optional] }
35
68
  end
36
69
  end
37
70
  end
@@ -1,3 +1,3 @@
1
1
  module Yuba
2
- VERSION = '0.0.1.pre'
2
+ VERSION = '0.0.5'
3
3
  end
@@ -1,26 +1,50 @@
1
1
  module Yuba
2
2
  class ViewModel
3
+ autoload :Rendering, 'yuba/view_model/rendering'
4
+
5
+ class_attribute :_properties
6
+ self._properties = {}
7
+
3
8
  class << self
4
- def success(**args)
5
- new(args.merge(success: true))
9
+ # You can register property to the class.
10
+ # Those registered by property need to be passed as arguments to the `initialize` except when `optional: true`
11
+ # is attached. You get `ArgumentError` if you don't pass `property` to `initialize`.
12
+ # Property is default to private. This means you can use it in internal the instance.
13
+ # If you it as public, use `public: true` option.
14
+ #
15
+ # property :name, public: true
16
+ # property :email, optional: true
17
+ def property(name, options = {})
18
+ self._properties = _properties.merge(name.to_sym => options)
6
19
  end
7
20
  end
8
21
 
9
- def initialize(success: true, **args)
10
- @success = success
11
- args.each { |k,v| self.class.send(:define_method, k) { v } }
22
+ def initialize(**args)
23
+ @_args = args
24
+ validate_arguments
25
+ define_accessors
12
26
  end
13
27
 
14
- def success?
15
- @success
16
- end
28
+ private
17
29
 
18
- def failure?
19
- !@success
30
+ attr_reader :_args
31
+
32
+ def validate_arguments
33
+ _args.each_key do |key|
34
+ if !_properties.has_key?(key.to_sym) && !_properties.dig(key.to_sym, :optional)
35
+ raise ArgumentError, "missing 'property :#{key}' in #{self.class.name} class"
36
+ end
37
+ end
20
38
  end
21
39
 
22
- def to_model
23
- form
40
+ def define_accessors
41
+ _args.each do |key, value|
42
+ public_method = _properties[key.to_sym][:public]
43
+ define_singleton_method key do
44
+ value
45
+ end
46
+ self.singleton_class.class_eval { private key.to_sym } unless public_method
47
+ end
24
48
  end
25
49
  end
26
50
  end
@@ -0,0 +1,38 @@
1
+ module Yuba
2
+ class ViewModel
3
+ module Rendering
4
+ def render(*args)
5
+ view_model_hash = args.find { |arg| arg.is_a?(Hash) && arg[:view_model] }
6
+ @_view_model = view_model_hash[:view_model] if view_model_hash && view_model_hash[:view_model]
7
+ super
8
+ end
9
+
10
+ def view_assigns
11
+ super.merge(view_model_assigns)
12
+ end
13
+
14
+ private
15
+
16
+ def _protected_ivars
17
+ super.merge(:@_view_model)
18
+ end
19
+
20
+ def view_model_assigns
21
+ return {} unless defined?(@_view_model)
22
+ methods = @_view_model.public_methods(false)
23
+ methods.reject! do |method_name|
24
+ %i[initialize].include?(method_name) ||
25
+ !valid_variable_name?(method_name)
26
+ end
27
+ methods.inject({}) do |hash, method_name|
28
+ hash[method_name] = @_view_model.public_send(method_name)
29
+ hash
30
+ end
31
+ end
32
+
33
+ def valid_variable_name?(name)
34
+ name.match?(/\A[_a-z]\w*\z/)
35
+ end
36
+ end
37
+ end
38
+ end
metadata CHANGED
@@ -1,29 +1,57 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: yuba
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1.pre
4
+ version: 0.0.5
5
5
  platform: ruby
6
6
  authors:
7
7
  - willnet
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2017-07-12 00:00:00.000000000 Z
11
+ date: 2021-01-29 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rails
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: 5.2.0
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: 5.2.0
27
+ - !ruby/object:Gem::Dependency
28
+ name: reform-rails
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: dry-types
15
43
  requirement: !ruby/object:Gem::Requirement
16
44
  requirements:
17
45
  - - "~>"
18
46
  - !ruby/object:Gem::Version
19
- version: 5.1.0
47
+ version: 0.12.2
20
48
  type: :runtime
21
49
  prerelease: false
22
50
  version_requirements: !ruby/object:Gem::Requirement
23
51
  requirements:
24
52
  - - "~>"
25
53
  - !ruby/object:Gem::Version
26
- version: 5.1.0
54
+ version: 0.12.2
27
55
  - !ruby/object:Gem::Dependency
28
56
  name: sqlite3
29
57
  requirement: !ruby/object:Gem::Requirement
@@ -38,6 +66,76 @@ dependencies:
38
66
  - - ">="
39
67
  - !ruby/object:Gem::Version
40
68
  version: '0'
69
+ - !ruby/object:Gem::Dependency
70
+ name: pry-rails
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ">="
74
+ - !ruby/object:Gem::Version
75
+ version: '0'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ">="
81
+ - !ruby/object:Gem::Version
82
+ version: '0'
83
+ - !ruby/object:Gem::Dependency
84
+ name: capybara
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - ">="
88
+ - !ruby/object:Gem::Version
89
+ version: '0'
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - ">="
95
+ - !ruby/object:Gem::Version
96
+ version: '0'
97
+ - !ruby/object:Gem::Dependency
98
+ name: puma
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - ">="
102
+ - !ruby/object:Gem::Version
103
+ version: '0'
104
+ type: :development
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - ">="
109
+ - !ruby/object:Gem::Version
110
+ version: '0'
111
+ - !ruby/object:Gem::Dependency
112
+ name: selenium-webdriver
113
+ requirement: !ruby/object:Gem::Requirement
114
+ requirements:
115
+ - - ">="
116
+ - !ruby/object:Gem::Version
117
+ version: '0'
118
+ type: :development
119
+ prerelease: false
120
+ version_requirements: !ruby/object:Gem::Requirement
121
+ requirements:
122
+ - - ">="
123
+ - !ruby/object:Gem::Version
124
+ version: '0'
125
+ - !ruby/object:Gem::Dependency
126
+ name: webdrivers
127
+ requirement: !ruby/object:Gem::Requirement
128
+ requirements:
129
+ - - ">="
130
+ - !ruby/object:Gem::Version
131
+ version: '0'
132
+ type: :development
133
+ prerelease: false
134
+ version_requirements: !ruby/object:Gem::Requirement
135
+ requirements:
136
+ - - ">="
137
+ - !ruby/object:Gem::Version
138
+ version: '0'
41
139
  description: Add New Layers to Rails. Form, Service, ViewModel.
42
140
  email:
43
141
  - netwillnet@gmail.com
@@ -48,14 +146,20 @@ files:
48
146
  - MIT-LICENSE
49
147
  - README.md
50
148
  - Rakefile
51
- - lib/tasks/crepe_tasks.rake
149
+ - lib/generators/yuba/form/form_generator.rb
150
+ - lib/generators/yuba/form/templates/form.tt
151
+ - lib/generators/yuba/service/service_generator.rb
152
+ - lib/generators/yuba/service/templates/service.tt
153
+ - lib/generators/yuba/view_model/templates/view_model.tt
154
+ - lib/generators/yuba/view_model/view_model_generator.rb
52
155
  - lib/yuba.rb
53
156
  - lib/yuba/form.rb
54
- - lib/yuba/form/attribute.rb
55
- - lib/yuba/form/attributes.rb
157
+ - lib/yuba/form/coercion.rb
158
+ - lib/yuba/form/multi_parameter_attributes.rb
56
159
  - lib/yuba/service.rb
57
160
  - lib/yuba/version.rb
58
161
  - lib/yuba/view_model.rb
162
+ - lib/yuba/view_model/rendering.rb
59
163
  homepage: https://github.com/willnet/yuba
60
164
  licenses:
61
165
  - MIT
@@ -71,12 +175,11 @@ required_ruby_version: !ruby/object:Gem::Requirement
71
175
  version: '0'
72
176
  required_rubygems_version: !ruby/object:Gem::Requirement
73
177
  requirements:
74
- - - ">"
178
+ - - ">="
75
179
  - !ruby/object:Gem::Version
76
- version: 1.3.1
180
+ version: '0'
77
181
  requirements: []
78
- rubyforge_project:
79
- rubygems_version: 2.6.11
182
+ rubygems_version: 3.1.2
80
183
  signing_key:
81
184
  specification_version: 4
82
185
  summary: Add New Layers to Rails
@@ -1,4 +0,0 @@
1
- # desc "Explaining what the task does"
2
- # task :yuba do
3
- # # Task goes here
4
- # end
@@ -1,9 +0,0 @@
1
- module Yuba
2
- class Form
3
- class Attribute
4
- def initialize(name)
5
- @name = name
6
- end
7
- end
8
- end
9
- end
@@ -1,44 +0,0 @@
1
- module Yuba
2
- module Form
3
- class Attributes
4
- class_attribute :attributes
5
- self.attributes = {}
6
-
7
- def initialize(value)
8
- yield if block_given?
9
- deep_assign(value)
10
- end
11
-
12
- def attribute(name, type: string, &block)
13
- mod = Module.new do
14
- define_method(name) do
15
- attributes[name.to_s]
16
- end
17
- define_method("#{name}=") do |value|
18
- write_attribute(name.to_s, value, block)
19
- end
20
- end
21
- include mod
22
- end
23
-
24
- private
25
-
26
- def write_attribute(name, value, block)
27
- # TODO: convert value by type of attribute
28
- value = Attributes.new(value, &block) if block
29
- attributes[name] = value
30
- end
31
-
32
- def deep_assign(value)
33
- raise ArgumentError unless value.is_a? Hash
34
- value.each do |k,v|
35
- if v.is_a? Hash
36
- deep_assign(v)
37
- else
38
- attributes[name.to_s] = v
39
- end
40
- end
41
- end
42
- end
43
- end
44
- end