fast_attributes_rails 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.coveralls.yml +1 -0
- data/.gitignore +17 -0
- data/.rspec +2 -0
- data/.travis.yml +6 -0
- data/CHANGELOG.md +194 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +22 -0
- data/README.md +292 -0
- data/Rakefile +1 -0
- data/benchmarks/Gemfile +8 -0
- data/benchmarks/comparison.rb +56 -0
- data/fast_attributes.gemspec +30 -0
- data/lib/fast_attributes.rb +83 -0
- data/lib/fast_attributes/builder.rb +125 -0
- data/lib/fast_attributes/default_attributes.rb +33 -0
- data/lib/fast_attributes/type_cast.rb +81 -0
- data/lib/fast_attributes/version.rb +3 -0
- data/spec/fast_attributes/type_cast_spec.rb +170 -0
- data/spec/fast_attributes_spec.rb +423 -0
- data/spec/fixtures/classes.rb +177 -0
- data/spec/spec_helper.rb +18 -0
- metadata +159 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: b789314937d4fe9b190cce7f27be1506803447e8
|
4
|
+
data.tar.gz: d9802b4d4caea346145bdccb2b839bf452a39eff
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 8932e7676e3a54707b3256d2ae93cd2a23412c6043f7ea24f9cec8ec9bef0b1e143e6e6fb3aed2e7ec24af26691dd7bc4bf8da4a6eb4b3ba01f9cb916cd06a64
|
7
|
+
data.tar.gz: d18ae5cf462917e8d3117fdd963a5d8e259504d6aa664b98c2c535f4d2506ad3dcbf74e46b8662f49cbd2a95320e99a465f7df611dcc5ce4902be7267c6c24fd
|
data/.coveralls.yml
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
service_name: travis-ci
|
data/.gitignore
ADDED
data/.rspec
ADDED
data/.travis.yml
ADDED
data/CHANGELOG.md
ADDED
@@ -0,0 +1,194 @@
|
|
1
|
+
**0.9.0 (September 15, 2016)**
|
2
|
+
* Attributes via accessors [Phil Schalm](https://github.com/pnomolos)
|
3
|
+
```ruby
|
4
|
+
class Book
|
5
|
+
extend FastAttributes
|
6
|
+
|
7
|
+
define_attributes attributes: :accessors do
|
8
|
+
attribute :author, String
|
9
|
+
end
|
10
|
+
|
11
|
+
def author
|
12
|
+
@author || "No author set"
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
book = Book.new
|
17
|
+
book.attributes
|
18
|
+
{"author" => "No author set"}
|
19
|
+
```
|
20
|
+
|
21
|
+
**0.8.0 (September 15, 2016)**
|
22
|
+
* Support of default values [Phil Schalm](https://github.com/pnomolos)
|
23
|
+
```ruby
|
24
|
+
class Product
|
25
|
+
extend FastAttributes
|
26
|
+
|
27
|
+
define_attributes initialize: true, attributes: true do
|
28
|
+
attribute :title, String, default: "Book"
|
29
|
+
attribute :price, Float, default: 10
|
30
|
+
end
|
31
|
+
end
|
32
|
+
```
|
33
|
+
|
34
|
+
**0.7.0 (August 31, 2014)**
|
35
|
+
* Support `boolean` data type as a lenient type.
|
36
|
+
```ruby
|
37
|
+
class Product
|
38
|
+
extend FastAttributes
|
39
|
+
attribute :active, :boolean
|
40
|
+
end
|
41
|
+
|
42
|
+
product = Product.new
|
43
|
+
product.active = 1
|
44
|
+
product.active # true
|
45
|
+
```
|
46
|
+
|
47
|
+
* Add support of lenient data types. It allows to define attribute which doesn't correspond to a specific ruby class
|
48
|
+
```ruby
|
49
|
+
FastAttributes.type_cast :lenient_attribute do
|
50
|
+
from '"yes"', to: 'true'
|
51
|
+
from '"no"', to: 'false'
|
52
|
+
otherwise 'nil'
|
53
|
+
end
|
54
|
+
|
55
|
+
class LenientAttributes
|
56
|
+
extend FastAttributes
|
57
|
+
attribute :terms_of_service, :lenient_attribute
|
58
|
+
end
|
59
|
+
|
60
|
+
lenient = LenientAttribute.new
|
61
|
+
lenient.terms_of_service = 'yes'
|
62
|
+
lenient.terms_of_service # true
|
63
|
+
```
|
64
|
+
|
65
|
+
* Allow to define default data types using class or symbol.
|
66
|
+
```ruby
|
67
|
+
class Book
|
68
|
+
extend FastAttributes
|
69
|
+
|
70
|
+
attribute :title String
|
71
|
+
attribute :pages, Integer
|
72
|
+
attribute :price, BigDecimal
|
73
|
+
attribute :authors, Array
|
74
|
+
attribute :published, Date
|
75
|
+
attribute :sold, Time
|
76
|
+
attribute :finished, DateTime
|
77
|
+
attribute :rate, Float
|
78
|
+
end
|
79
|
+
|
80
|
+
class LenientBook
|
81
|
+
extend FastAttributes
|
82
|
+
|
83
|
+
attribute :title, :string
|
84
|
+
attribute :pages, :integer
|
85
|
+
attribute :price, :big_decimal
|
86
|
+
attribute :authors, :array
|
87
|
+
attribute :published, :date
|
88
|
+
attribute :sold, :time
|
89
|
+
attribute :finished, :date_time
|
90
|
+
attribute :rate, :float
|
91
|
+
end
|
92
|
+
```
|
93
|
+
|
94
|
+
**0.6.0 (July 20, 2014)**
|
95
|
+
* Throw custom `FastAttributes::TypeCast::InvalidValueError` exception when value has invalid type.
|
96
|
+
How auto-generated method looks like:
|
97
|
+
```ruby
|
98
|
+
FastAttributes.set_type_casting(String, 'String(%s)')
|
99
|
+
# def name=(value)
|
100
|
+
# @name = begin
|
101
|
+
# case value
|
102
|
+
# when nil then nil
|
103
|
+
# when String then value
|
104
|
+
# else String(value)
|
105
|
+
# end
|
106
|
+
# rescue => e
|
107
|
+
# raise FastAttributes::TypeCast::InvalidValueError, %(Invalid value "#{value}" for attribute "name" of type "String")
|
108
|
+
# end
|
109
|
+
# end
|
110
|
+
```
|
111
|
+
|
112
|
+
* Add `on_error` method to override default rescue block:
|
113
|
+
```ruby
|
114
|
+
FastAttributes.type_cast String do
|
115
|
+
from 'nil', to: 'nil'
|
116
|
+
from 'String', to: '%s'
|
117
|
+
otherwise 'String(%s)'
|
118
|
+
on_error 'ArgumentError', act: 'nil'
|
119
|
+
on_error 'TypeError', act: '""'
|
120
|
+
on_error 'StandardError', act: 'e.message'
|
121
|
+
end
|
122
|
+
|
123
|
+
# def name=(value)
|
124
|
+
# @name = begin
|
125
|
+
# case value
|
126
|
+
# when nil then nil
|
127
|
+
# when String then value
|
128
|
+
# else String(value)
|
129
|
+
# end
|
130
|
+
# rescue ArgumentError => e
|
131
|
+
# nil
|
132
|
+
# rescue TypeError => e
|
133
|
+
# ""
|
134
|
+
# rescue StandardError => e
|
135
|
+
# e.message
|
136
|
+
# end
|
137
|
+
# end
|
138
|
+
```
|
139
|
+
|
140
|
+
**0.5.2 (July 18, 2014)**
|
141
|
+
* Throw proper exception when type casting function is not defined
|
142
|
+
|
143
|
+
**0.5.1 (July 16, 2014)**
|
144
|
+
* Fix `BigDecimal` type casting. It threw an exception when input value was `Float`
|
145
|
+
|
146
|
+
**0.5.0 (July 16, 2014)**
|
147
|
+
* Allow to control any switch statements during typecasting using new DSL.
|
148
|
+
|
149
|
+
The default typecasting rule which `fast_attributes` generates for `String` is:
|
150
|
+
```ruby
|
151
|
+
case value
|
152
|
+
when nil then nil
|
153
|
+
when String then value
|
154
|
+
else String(%s)
|
155
|
+
end
|
156
|
+
```
|
157
|
+
Method `FastAttributes.set_type_casting` allows only to change `else` condition.
|
158
|
+
```ruby
|
159
|
+
FastAttributes.set_type_casting(String, 'String("#{%s}-suffix")')
|
160
|
+
```
|
161
|
+
|
162
|
+
Using `FastAttributes.type_cast` method it's possible to define custom `switch` condition
|
163
|
+
```ruby
|
164
|
+
FastAttributes.type_cast String do # case value
|
165
|
+
from 'nil', to: 'nil' # when nil then nil
|
166
|
+
from 'String', to: '%s' # when String then value
|
167
|
+
from Array, to: 'raise "Error"' # when Array then raise "Error"
|
168
|
+
otherwise 'String(%s)' # else String(value)
|
169
|
+
end # end
|
170
|
+
```
|
171
|
+
|
172
|
+
* Add support to BigDecimal [Filipe Costa](https://github.com/applift/fast_attributes/pull/2)
|
173
|
+
|
174
|
+
**0.4.0 (July 5, 2014)**
|
175
|
+
* Allow to override generated methods
|
176
|
+
|
177
|
+
**0.3.0 (July 4, 2014)**
|
178
|
+
* Support `Float` data type
|
179
|
+
|
180
|
+
**0.2.2 (July 2, 2014)**
|
181
|
+
* Fix uninitialized `@type_casting` variable
|
182
|
+
|
183
|
+
**0.2.1 (June 27, 2014)**
|
184
|
+
* Set minimum ruby version to `1.9.2`
|
185
|
+
|
186
|
+
**0.2.0 (June 27, 2014)**
|
187
|
+
* Add `define_attributes` method which allows to generate `initialize` and `attributes`
|
188
|
+
* Raise `FastAttributes::UnsupportedTypeError` error when unknown attribute type is specified
|
189
|
+
|
190
|
+
**0.1.0 (June 26, 2014)**
|
191
|
+
* Support `Integer`, `String`, `Array`, `Date`, `Time` and `DateTime` attribute types
|
192
|
+
|
193
|
+
**0.0.1 (June 20, 2014)**
|
194
|
+
* Initial commit
|
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2014 AppLift GmbH
|
2
|
+
|
3
|
+
MIT License
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
+
a copy of this software and associated documentation files (the
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
11
|
+
the following conditions:
|
12
|
+
|
13
|
+
The above copyright notice and this permission notice shall be
|
14
|
+
included in all copies or substantial portions of the Software.
|
15
|
+
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,292 @@
|
|
1
|
+
# FastAttributes
|
2
|
+
[![Gem Version](http://img.shields.io/gem/v/fast_attributes.svg)](http://rubygems.org/gems/fast_attributes)
|
3
|
+
[![Build Status](http://img.shields.io/travis/applift/fast_attributes.svg)](https://travis-ci.org/applift/fast_attributes)
|
4
|
+
[![Coverage Status](http://img.shields.io/coveralls/applift/fast_attributes.svg)](https://coveralls.io/r/applift/fast_attributes?branch=master)
|
5
|
+
[![Code Climate](http://img.shields.io/codeclimate/github/applift/fast_attributes.svg)](https://codeclimate.com/github/applift/fast_attributes)
|
6
|
+
[![Dependency Status](http://img.shields.io/gemnasium/applift/fast_attributes.svg)](https://gemnasium.com/applift/fast_attributes)
|
7
|
+
|
8
|
+
## Motivation
|
9
|
+
There are already a lot of good and flexible gems which solve a similar problem, allowing attributes to be defined with their types, for example: [virtus](https://github.com/solnic/virtus) or [attrio](https://github.com/jetrockets/attrio). However, the disadvantage of these gems is performance. So, the goal of `fast_attributes` is to provide a simple solution which is fast, understandable and extendable.
|
10
|
+
|
11
|
+
This is the [performance benchmark](https://github.com/applift/fast_attributes/blob/master/benchmarks/comparison.rb) of `fast_attributes` compared to other popular gems.
|
12
|
+
|
13
|
+
```
|
14
|
+
Comparison:
|
15
|
+
FastAttributes: without values : 1528209.4 i/s
|
16
|
+
FastAttributes: integer values for integer attributes: 88794.2 i/s - 17.21x slower
|
17
|
+
FastAttributes: string values for integer attributes : 77673.3 i/s - 19.67x slower
|
18
|
+
Virtus: integer values for integer attributes : 21104.7 i/s - 72.41x slower
|
19
|
+
Attrio: integer values for integer attributes : 11932.2 i/s - 128.07x slower
|
20
|
+
Attrio: string values for integer attributes : 11007.2 i/s - 138.84x slower
|
21
|
+
Virtus: without values : 10151.0 i/s - 150.55x slower
|
22
|
+
Attrio: without values : 7164.3 i/s - 213.31x slower
|
23
|
+
Virtus: string values for integer attributes : 3195.6 i/s - 478.22x slower
|
24
|
+
```
|
25
|
+
|
26
|
+
## Installation
|
27
|
+
|
28
|
+
Add this line to your application's Gemfile:
|
29
|
+
|
30
|
+
gem 'fast_attributes'
|
31
|
+
|
32
|
+
And then execute:
|
33
|
+
|
34
|
+
$ bundle
|
35
|
+
|
36
|
+
Or install it yourself as:
|
37
|
+
|
38
|
+
$ gem install fast_attributes
|
39
|
+
|
40
|
+
## Usage
|
41
|
+
|
42
|
+
Define getter/setter methods:
|
43
|
+
```ruby
|
44
|
+
class Book
|
45
|
+
extend FastAttributes
|
46
|
+
|
47
|
+
attribute :title, :name, String
|
48
|
+
attribute :pages, Integer
|
49
|
+
attribute :authors, Array
|
50
|
+
attribute :published, Date
|
51
|
+
attribute :sold, Time
|
52
|
+
attribute :finished, DateTime
|
53
|
+
end
|
54
|
+
|
55
|
+
book = Book.new
|
56
|
+
book.title = 'There and Back Again'
|
57
|
+
book.name = 'The Hobbit'
|
58
|
+
book.pages = '200'
|
59
|
+
book.authors = 'Tolkien'
|
60
|
+
book.published = '1937-09-21'
|
61
|
+
book.sold = '2014-06-25 13:45'
|
62
|
+
book.finished = '1937-08-20 12:35'
|
63
|
+
|
64
|
+
#<Book:0x007f9a0110be20
|
65
|
+
@authors=["Tolkien"],
|
66
|
+
@finished=
|
67
|
+
#<DateTime: 1937-08-20T12:35:00+00:00 ((2428766j,45300s,0n),+0s,2299161j)>,
|
68
|
+
@name="The Hobbit",
|
69
|
+
@pages=200,
|
70
|
+
@published=#<Date: 1937-09-21 ((2428798j,0s,0n),+0s,2299161j)>,
|
71
|
+
@sold=2014-06-25 13:45:00 +0200,
|
72
|
+
@title="There and Back Again">
|
73
|
+
```
|
74
|
+
|
75
|
+
To generate `initialize` and `attributes` methods, attribute definition should be wrapped with `define_attributes`:
|
76
|
+
```ruby
|
77
|
+
class Book
|
78
|
+
extend FastAttributes
|
79
|
+
|
80
|
+
define_attributes initialize: true, attributes: true do
|
81
|
+
attribute :title, :name, String
|
82
|
+
attribute :pages, Integer
|
83
|
+
attribute :authors, Array
|
84
|
+
attribute :published, Date
|
85
|
+
attribute :sold, Time
|
86
|
+
attribute :finished, DateTime
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
book = Book.new(
|
91
|
+
title: 'There and Back Again',
|
92
|
+
name: 'The Hobbit',
|
93
|
+
pages: '200',
|
94
|
+
authors: 'Tolkien',
|
95
|
+
published: '1937-09-21',
|
96
|
+
sold: '2014-06-25 13:45',
|
97
|
+
finished: '1937-08-20 12:35'
|
98
|
+
)
|
99
|
+
|
100
|
+
book.attributes
|
101
|
+
{"title"=>"There and Back Again",
|
102
|
+
"name"=>"The Hobbit",
|
103
|
+
"pages"=>200,
|
104
|
+
"authors"=>["Tolkien"],
|
105
|
+
"published"=>#<Date: 1937-09-21 ((2428798j,0s,0n),+0s,2299161j)>,
|
106
|
+
"sold"=>2014-06-25 13:45:00 +0200,
|
107
|
+
"finished"=>
|
108
|
+
#<DateTime: 1937-08-20T12:35:00+00:00 ((2428766j,45300s,0n),+0s,2299161j)>}
|
109
|
+
```
|
110
|
+
|
111
|
+
## Default values
|
112
|
+
|
113
|
+
Requires `define_attributes` to be used with `initialize: true` (this is where the default values are set):
|
114
|
+
|
115
|
+
```ruby
|
116
|
+
class Book
|
117
|
+
extend FastAttributes
|
118
|
+
|
119
|
+
define_attributes initialize: true do
|
120
|
+
attribute :author, String, default: "Some String"
|
121
|
+
end
|
122
|
+
end
|
123
|
+
|
124
|
+
book = Book.new
|
125
|
+
book.attributes
|
126
|
+
{"author" => "Some String"}
|
127
|
+
```
|
128
|
+
|
129
|
+
## Attributes via accessors
|
130
|
+
|
131
|
+
Sometimes you want `attributes` to return the value of your accessors, rather than the instance variables.
|
132
|
+
This is slower than using ivars directly, so use `attributes: :accessors`:
|
133
|
+
|
134
|
+
```ruby
|
135
|
+
class Book
|
136
|
+
extend FastAttributes
|
137
|
+
|
138
|
+
define_attributes attributes: :accessors do
|
139
|
+
attribute :author, String
|
140
|
+
end
|
141
|
+
|
142
|
+
def author
|
143
|
+
@author || "No author set"
|
144
|
+
end
|
145
|
+
end
|
146
|
+
|
147
|
+
book = Book.new
|
148
|
+
book.attributes
|
149
|
+
{"author" => "No author set"}
|
150
|
+
```
|
151
|
+
|
152
|
+
|
153
|
+
## Custom Type
|
154
|
+
It's easy to add a custom attribute type.
|
155
|
+
```ruby
|
156
|
+
FastAttributes.set_type_casting(OpenStruct, 'OpenStruct.new(name: %s)')
|
157
|
+
|
158
|
+
class Book
|
159
|
+
extend FastAttributes
|
160
|
+
attribute :author, OpenStruct
|
161
|
+
end
|
162
|
+
|
163
|
+
book = Book.new
|
164
|
+
book.author = 'Rowling'
|
165
|
+
book.author
|
166
|
+
# => #<OpenStruct name="Rowling">
|
167
|
+
```
|
168
|
+
|
169
|
+
Notice, that second parameter is a string. It's necessary because this code is compiled into a ruby method in runtime. The placeholder `%s` represents a value which this method accepts.
|
170
|
+
|
171
|
+
It's possible to refer to a placeholder several times.
|
172
|
+
```ruby
|
173
|
+
Size = Class.new(Array)
|
174
|
+
FastAttributes.set_type_casting Size, <<-EOS
|
175
|
+
Size[%s, %s]
|
176
|
+
EOS
|
177
|
+
|
178
|
+
class Square
|
179
|
+
extend FastAttributes
|
180
|
+
attribute :size, Size
|
181
|
+
end
|
182
|
+
|
183
|
+
square = Square.new
|
184
|
+
square.size = 5
|
185
|
+
square.size
|
186
|
+
# => [5, 5]
|
187
|
+
```
|
188
|
+
|
189
|
+
Method `FastAttributes.set_type_casting` generates the following template:
|
190
|
+
```ruby
|
191
|
+
FastAttributes.set_type_casting String, 'String(%s)'
|
192
|
+
# begin
|
193
|
+
# case %s
|
194
|
+
# when nil then nil
|
195
|
+
# when String then %s
|
196
|
+
# else String(%s)
|
197
|
+
# end
|
198
|
+
# rescue => e
|
199
|
+
# raise FastAttributes::TypeCast::InvalidValueError, %(Invalid value "\#{%s}" for attribute "%a" of type "String")
|
200
|
+
# end
|
201
|
+
```
|
202
|
+
and when the attribute is defined, `fast_attributes` generates the following setter method:
|
203
|
+
```ruby
|
204
|
+
class A
|
205
|
+
extend FastAttributes
|
206
|
+
attribute :name, String
|
207
|
+
end
|
208
|
+
|
209
|
+
# def name=(value)
|
210
|
+
# @name = begin
|
211
|
+
# case value
|
212
|
+
# when nil then nil
|
213
|
+
# when String then value
|
214
|
+
# else String(value)
|
215
|
+
# end
|
216
|
+
# rescue => e
|
217
|
+
# raise FastAttributes::TypeCast::InvalidValueError, %(Invalid value "#{value}" for attribute "name" of type "String")
|
218
|
+
# end
|
219
|
+
# end
|
220
|
+
```
|
221
|
+
Notice, placeholder `%a` represents method name. Also, `set_type_casting` method generates lenient date type. See [Lenient Data Types](https://github.com/applift/fast_attributes/blob/lenient_data_types/README.md#lenient-data-types) section.
|
222
|
+
|
223
|
+
If you need to conrol the whole type casting process, you can use the following DSL:
|
224
|
+
```ruby
|
225
|
+
FastAttributes.type_cast String do # begin
|
226
|
+
# case String
|
227
|
+
from 'nil', to: 'nil' # when nil then nil
|
228
|
+
from 'String', to: '%s' # when String then %s
|
229
|
+
otherwise 'String(%s)' # else String(%s)
|
230
|
+
# end
|
231
|
+
on_error 'TypeError', act: 'nil' # rescue TypeError => e
|
232
|
+
# nil
|
233
|
+
on_error 'StandardError', act: '""' # rescue StandardError => e
|
234
|
+
# ""
|
235
|
+
end # end
|
236
|
+
```
|
237
|
+
|
238
|
+
## Lenient Data Types
|
239
|
+
It's also possible to define a lenient data type which doesn't correspond to any of ruby classes:
|
240
|
+
```ruby
|
241
|
+
FastAttributes.type_cast :yes_no do
|
242
|
+
from '"yes"', to: 'true'
|
243
|
+
from '"no"', to: 'false'
|
244
|
+
otherwise 'nil'
|
245
|
+
end
|
246
|
+
|
247
|
+
class Order
|
248
|
+
extend FastAttributes
|
249
|
+
|
250
|
+
attribute :terms_of_service, :yes_no
|
251
|
+
end
|
252
|
+
|
253
|
+
order = Order.new
|
254
|
+
order.terms_of_service = 'yes'
|
255
|
+
order.terms_of_service
|
256
|
+
# => true
|
257
|
+
order.terms_of_service = 'no'
|
258
|
+
order.terms_of_service
|
259
|
+
# => false
|
260
|
+
order.terms_of_service = 42
|
261
|
+
order.terms_of_service
|
262
|
+
# => nil
|
263
|
+
```
|
264
|
+
|
265
|
+
All default data types have lenient notation:
|
266
|
+
```ruby
|
267
|
+
class Book
|
268
|
+
extend FastAttributes
|
269
|
+
|
270
|
+
attribute :title, :string
|
271
|
+
attribute :pages, :integer
|
272
|
+
attribute :price, :big_decimal
|
273
|
+
attribute :authors, :array
|
274
|
+
attribute :published, :date
|
275
|
+
attribute :sold, :time
|
276
|
+
attribute :finished, :date_time
|
277
|
+
attribute :rate, :float
|
278
|
+
attribute :active, :boolean
|
279
|
+
end
|
280
|
+
```
|
281
|
+
Notice, `Boolean` attribute can be defined only via symbol, `fast_attribute` doesn't create `Boolean` class.
|
282
|
+
|
283
|
+
## Extensions
|
284
|
+
* [fast_attributes-uuid](https://github.com/applift/fast_attributes-uuid) - adds support of `UUID` to `fast_attributes`
|
285
|
+
|
286
|
+
## Contributing
|
287
|
+
|
288
|
+
1. Fork it ( http://github.com/applift/fast_attributes/fork )
|
289
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
290
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
291
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
292
|
+
5. Create new Pull Request
|