ciesta 0.2.3 → 0.2.4

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 686725e6d7930c99dafab26c796538ac28410261704491f9f676bb2204950481
4
- data.tar.gz: 16b64dd435105dcc1a66c778e4cd321137b47d4859588a1b9c5f4d19ae7c4e42
3
+ metadata.gz: bb2964e90401b855dc16d22aaa8f33634a4994080ec94b4db9a52f8cd3a6a519
4
+ data.tar.gz: 80631e5019a4e21759777edb3aaf70429699533a278ecad419d1c09ae11fe9c1
5
5
  SHA512:
6
- metadata.gz: 12cce79f11ee00426ad3675c2bb1506a28b526ab0b565dae0719945661261c9d62fe6c01210f2d68697b595e174fc1c4e6f015d823adae3cf9a9ab83c63a73f9
7
- data.tar.gz: 5b98c72dd163212fdea889553d501f486df12ddc7dfcd3ba73d6e09aae4e9d11afd0a61b0a1f5927fc0fd4fcbe4c937aef9ed5413b174d18923b9a07a25a9598
6
+ metadata.gz: 7c752c91de5d1a7d8f0d284193f19b61dbd76666ed013e1dc83f5ce597849636153fc3151c405dbe37e1635d5acb5f354c3ab9ed6d7580beb78270ed1497eac8
7
+ data.tar.gz: ea33aa1779f0bcb4d79df9c3218c3302113f111d9417dadec5d0e8171859006a0f3d24a4dbd943f9405bc6dae26c27d5fc56db52c973e4d2440c5e11a62118cc
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- ciesta (0.2.3)
4
+ ciesta (0.2.4)
5
5
  dry-types (~> 0.12.1)
6
6
  dry-validation (~> 0.11.1)
7
7
 
data/README.md CHANGED
@@ -18,6 +18,7 @@ You should keep it in mind that here uses [dry-validation](https://github.com/dr
18
18
  - [Advanced field declaration](#advanced-field-declaration)
19
19
  - [Types](#types)
20
20
  - [Default value](#default-value)
21
+ - [Virtual field](#virtual-field)
21
22
  - [Values mass update](#values-mass-update)
22
23
  - [Contributing](#contributing)
23
24
  - [License](#license)
@@ -122,6 +123,7 @@ field :age, type: Ciesta::Types::Coercible::Int
122
123
  form.age = "42"
123
124
  form.age # => 42
124
125
  ```
126
+
125
127
  Default type is `Ciesta::Types::Any`.
126
128
 
127
129
  #### Default value
@@ -149,6 +151,19 @@ field :age, default: -> { default_age }
149
151
  form.age # => 42
150
152
  ```
151
153
 
154
+ ### Virtual field
155
+ You can declare field as "virtual". It means that when you call `sync!` it will not raise an error "model attribute is not defined".
156
+
157
+ ```ruby
158
+ User = Struct.new(:name)
159
+ ...
160
+ field :age, virtual: true
161
+ ...
162
+ form.age = "42"
163
+ form.age # => 42
164
+ form.sync! # => true
165
+ ```
166
+
152
167
  ## Values mass update
153
168
  There are two methods for form fields mass update: `assign` and `assign!`.
154
169
 
@@ -10,6 +10,9 @@ module Ciesta
10
10
  # Error for missing field definition
11
11
  FieldNotDefined = Class.new(NoMethodError)
12
12
 
13
+ # Error for missing method of model
14
+ AttributeNotDefined = Class.new(NoMethodError)
15
+
13
16
  # Error for nil object
14
17
  ModelNotPresent = Class.new(StandardError)
15
18
  end
@@ -20,6 +20,7 @@ class Ciesta::Field
20
20
  @name = name.to_sym
21
21
  @type = options.delete(:type) || DEFAULT_TYPE
22
22
  @default = options.delete(:default)
23
+ @virtual = options.delete(:virtual) || false
23
24
  end
24
25
 
25
26
  # Sets a new value for field
@@ -51,13 +52,22 @@ class Ciesta::Field
51
52
  @binding = obj
52
53
  end
53
54
 
55
+ # Returns true if field is virtual
56
+ #
57
+ # @api private
58
+ #
59
+ # @return [Boolean]
60
+ def virtual?
61
+ @virtual
62
+ end
63
+
54
64
  private
55
65
 
56
66
  # Returns typed default value for field
57
67
  #
58
68
  # @api private
59
- # @return [any]
60
69
  # @raise Ciesta::ViolatesConstraints
70
+ # @return [any]
61
71
  def default
62
72
  type[raw_default]
63
73
  rescue Dry::Types::ConstraintError
@@ -84,7 +84,7 @@ class Ciesta::FieldList
84
84
  # @api private
85
85
  # @param [Block] block Block to iterate
86
86
  def each
87
- list.each { |name, field| yield(name, field.value) }
87
+ list.each_value { |field| yield(field) }
88
88
  end
89
89
 
90
90
  private
@@ -16,6 +16,11 @@ class Ciesta::Form
16
16
  # @see Ciesta::Validator
17
17
  delegate :errors, to: :validator
18
18
 
19
+ # @!method sync
20
+ # @!method sync!
21
+ # @see Ciesta::Syncer
22
+ delegate :sync, to: :syncer
23
+
19
24
  class << self
20
25
  # Declare new form field
21
26
  #
@@ -65,7 +70,10 @@ class Ciesta::Form
65
70
 
66
71
  return if object.nil?
67
72
 
68
- values = fields.keys.map { |key| [key, object.public_send(key)] }.to_h
73
+ values = fields.keys.each_with_object({}) do |key, mem|
74
+ mem[key] = object.public_send(key) if object.respond_to?(key)
75
+ end
76
+
69
77
  assign(values)
70
78
  end
71
79
 
@@ -89,21 +97,8 @@ class Ciesta::Form
89
97
  # @raise Ciesta::FormNotValid
90
98
  # @return [Boolean]
91
99
  def sync!(&block)
92
- raise Ciesta::ModelNotPresent, "Model not present" if object.nil?
93
100
  raise Ciesta::FormNotValid, "Form is not valid" unless valid?
94
- syncer.sync(&block)
95
- end
96
-
97
- # Sync form attributes to object
98
- #
99
- # @see Ciesta::Syncer
100
- #
101
- # @param [Block] block Block wich will be yielded after synfing
102
- #
103
- # @return [Boolean]
104
- def sync(&block)
105
- return if object.nil?
106
- syncer.sync(&block)
101
+ syncer.sync!(&block)
107
102
  end
108
103
 
109
104
  private
@@ -8,20 +8,45 @@ class Ciesta::Syncer
8
8
  # Constructor
9
9
  #
10
10
  # @api private
11
- # @param [Object] object Form objecr
11
+ # @param [Object] object Form object
12
12
  # @param [Ciesta::FieldList] fields Field list
13
13
  def initialize(object, fields)
14
14
  @object = object
15
15
  @fields = fields
16
16
  end
17
17
 
18
- # Sync attributes with objec
18
+ # Sync attributes with object
19
19
  #
20
20
  # @param [Block] block Block which will be yielded after syncing
21
21
  #
22
22
  # @return [Booelan]
23
23
  def sync
24
- fields.each { |name, value| object.send("#{name}=", value) }
24
+ return if object.nil?
25
+
26
+ fields.each do |field|
27
+ begin
28
+ save_to_object(field)
29
+ rescue StandardError
30
+ nil
31
+ end
32
+ end
33
+
34
+ yield(object) if block_given?
35
+
36
+ true
37
+ end
38
+
39
+ # Sync attributes with object
40
+ #
41
+ # @param [Block] block Block which will be yielded after syncing
42
+ #
43
+ # @raise Ciesta::ModelNotPresent
44
+ # @raise Ciesta::AttributeNotDefined
45
+ # @return [Booelan]
46
+ def sync!
47
+ raise Ciesta::ModelNotPresent, "Cannot sync without model" if object.nil?
48
+
49
+ fields.each { |field| save_to_object(field) }
25
50
 
26
51
  yield(object) if block_given?
27
52
 
@@ -31,4 +56,10 @@ class Ciesta::Syncer
31
56
  private
32
57
 
33
58
  attr_reader :object, :fields
59
+
60
+ def save_to_object(field)
61
+ object.send("#{field.name}=", field.value) unless field.virtual?
62
+ rescue NoMethodError
63
+ raise Ciesta::AttributeNotDefined, "Attribute #{field.name} is not defined on model"
64
+ end
34
65
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Ciesta
4
- VERSION = "0.2.3".freeze
4
+ VERSION = "0.2.4".freeze
5
5
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ciesta
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.3
4
+ version: 0.2.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Alexey