cassandra_object_rails 0.0.1
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 +15 -0
- data/.gitignore +3 -0
- data/.travis.yml +7 -0
- data/CHANGELOG +5 -0
- data/Gemfile +8 -0
- data/LICENSE +13 -0
- data/MIT-LICENSE +20 -0
- data/README.rdoc +97 -0
- data/Rakefile +12 -0
- data/cassandra_object_rails.gemspec +26 -0
- data/lib/cassandra_object/attribute_methods.rb +87 -0
- data/lib/cassandra_object/attribute_methods/definition.rb +19 -0
- data/lib/cassandra_object/attribute_methods/dirty.rb +44 -0
- data/lib/cassandra_object/attribute_methods/primary_key.rb +25 -0
- data/lib/cassandra_object/attribute_methods/typecasting.rb +59 -0
- data/lib/cassandra_object/base.rb +69 -0
- data/lib/cassandra_object/belongs_to.rb +63 -0
- data/lib/cassandra_object/belongs_to/association.rb +48 -0
- data/lib/cassandra_object/belongs_to/builder.rb +40 -0
- data/lib/cassandra_object/belongs_to/reflection.rb +30 -0
- data/lib/cassandra_object/callbacks.rb +29 -0
- data/lib/cassandra_object/config.rb +15 -0
- data/lib/cassandra_object/connection.rb +36 -0
- data/lib/cassandra_object/consistency.rb +18 -0
- data/lib/cassandra_object/core.rb +59 -0
- data/lib/cassandra_object/errors.rb +6 -0
- data/lib/cassandra_object/identity.rb +24 -0
- data/lib/cassandra_object/inspect.rb +25 -0
- data/lib/cassandra_object/log_subscriber.rb +29 -0
- data/lib/cassandra_object/persistence.rb +169 -0
- data/lib/cassandra_object/rails_initializer.rb +19 -0
- data/lib/cassandra_object/railtie.rb +11 -0
- data/lib/cassandra_object/savepoints.rb +79 -0
- data/lib/cassandra_object/schema.rb +78 -0
- data/lib/cassandra_object/schema/tasks.rb +48 -0
- data/lib/cassandra_object/scope.rb +48 -0
- data/lib/cassandra_object/scope/batches.rb +32 -0
- data/lib/cassandra_object/scope/finder_methods.rb +47 -0
- data/lib/cassandra_object/scope/query_methods.rb +111 -0
- data/lib/cassandra_object/scoping.rb +19 -0
- data/lib/cassandra_object/serialization.rb +6 -0
- data/lib/cassandra_object/tasks/cassandra.rake +53 -0
- data/lib/cassandra_object/timestamps.rb +19 -0
- data/lib/cassandra_object/type.rb +16 -0
- data/lib/cassandra_object/types.rb +8 -0
- data/lib/cassandra_object/types/array_type.rb +76 -0
- data/lib/cassandra_object/types/base_type.rb +26 -0
- data/lib/cassandra_object/types/boolean_type.rb +20 -0
- data/lib/cassandra_object/types/date_type.rb +17 -0
- data/lib/cassandra_object/types/float_type.rb +16 -0
- data/lib/cassandra_object/types/integer_type.rb +16 -0
- data/lib/cassandra_object/types/json_type.rb +52 -0
- data/lib/cassandra_object/types/string_type.rb +15 -0
- data/lib/cassandra_object/types/time_type.rb +16 -0
- data/lib/cassandra_object/validations.rb +44 -0
- data/lib/cassandra_object_rails.rb +64 -0
- data/test/support/connect.rb +17 -0
- data/test/support/issue.rb +5 -0
- data/test/support/teardown.rb +24 -0
- data/test/test_helper.rb +34 -0
- data/test/unit/active_model_test.rb +18 -0
- data/test/unit/attribute_methods/definition_test.rb +13 -0
- data/test/unit/attribute_methods/dirty_test.rb +71 -0
- data/test/unit/attribute_methods/primary_key_test.rb +26 -0
- data/test/unit/attribute_methods/typecasting_test.rb +112 -0
- data/test/unit/attribute_methods_test.rb +39 -0
- data/test/unit/base_test.rb +20 -0
- data/test/unit/belongs_to/reflection_test.rb +12 -0
- data/test/unit/belongs_to_test.rb +62 -0
- data/test/unit/callbacks_test.rb +46 -0
- data/test/unit/config_test.rb +23 -0
- data/test/unit/connection_test.rb +10 -0
- data/test/unit/consistency_test.rb +13 -0
- data/test/unit/core_test.rb +55 -0
- data/test/unit/identity_test.rb +26 -0
- data/test/unit/inspect_test.rb +26 -0
- data/test/unit/log_subscriber_test.rb +22 -0
- data/test/unit/persistence_test.rb +187 -0
- data/test/unit/savepoints_test.rb +35 -0
- data/test/unit/schema/tasks_test.rb +29 -0
- data/test/unit/schema_test.rb +47 -0
- data/test/unit/scope/batches_test.rb +30 -0
- data/test/unit/scope/finder_methods_test.rb +51 -0
- data/test/unit/scope/query_methods_test.rb +26 -0
- data/test/unit/scoping_test.rb +7 -0
- data/test/unit/timestamps_test.rb +27 -0
- data/test/unit/types/array_type_test.rb +71 -0
- data/test/unit/types/base_type_test.rb +24 -0
- data/test/unit/types/boolean_type_test.rb +24 -0
- data/test/unit/types/date_type_test.rb +11 -0
- data/test/unit/types/float_type_test.rb +17 -0
- data/test/unit/types/integer_type_test.rb +19 -0
- data/test/unit/types/json_type_test.rb +77 -0
- data/test/unit/types/string_type_test.rb +32 -0
- data/test/unit/types/time_type_test.rb +14 -0
- data/test/unit/validations_test.rb +27 -0
- metadata +208 -0
checksums.yaml
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
---
|
2
|
+
!binary "U0hBMQ==":
|
3
|
+
metadata.gz: !binary |-
|
4
|
+
ZjY5MDAwZDcwYmFlYmYxYjhjYWZlY2Y2YjNhZWM2MmI0YjQzN2Y2Yw==
|
5
|
+
data.tar.gz: !binary |-
|
6
|
+
MDRkMDJiYmE2OTg2ODhjZDlmYWYxMzk2ZjM4MmI2YjQ0YzA3ZTk4Yw==
|
7
|
+
!binary "U0hBNTEy":
|
8
|
+
metadata.gz: !binary |-
|
9
|
+
YzA5YjVmZTI3MzUzYmJiNTI2YjAyMjM5OWRlNzc2NGE5M2M4MzRlN2NiMzli
|
10
|
+
NGE0MjA1OTAwMDNhOTY1NzZhMzEzMTA1OWJjZWNkMTgzMDI4NDE5YmZhYjY2
|
11
|
+
OGE3OTRjY2I3NmMxOWFlY2JhY2E4NmM5Yzk4ZDk3OWM2NGNmZDg=
|
12
|
+
data.tar.gz: !binary |-
|
13
|
+
NDE0YjU3ZTQ3NjY0MjU2MDkxZWM1M2JiMDI0ZjRjZjc0MDE4MDJiMTJlZDQ5
|
14
|
+
NDNlZGQ4NGUxY2NhNDdkNDk2ZWQ0OTExNmJmOWY3ZDU5ODY4M2Y5MjJlODcz
|
15
|
+
Njk2MDBjMmNmNzczNWUyYWEwYzI2YjlhOTUzODMyZWNkNGQ5ZTY=
|
data/.gitignore
ADDED
data/.travis.yml
ADDED
data/CHANGELOG
ADDED
data/Gemfile
ADDED
data/LICENSE
ADDED
@@ -0,0 +1,13 @@
|
|
1
|
+
Copyright (c) 2009 Koziarski Software Ltd
|
2
|
+
|
3
|
+
Permission to use, copy, modify, and/or distribute this software for any
|
4
|
+
purpose with or without fee is hereby granted, provided that the above
|
5
|
+
copyright notice and this permission notice appear in all copies.
|
6
|
+
|
7
|
+
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
8
|
+
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
9
|
+
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
10
|
+
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
11
|
+
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
12
|
+
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
13
|
+
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
data/MIT-LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright (c) 2011 [Michael Koziarski]
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.rdoc
ADDED
@@ -0,0 +1,97 @@
|
|
1
|
+
== Cassandra Object Rails
|
2
|
+
|
3
|
+
Cassandra Object uses ActiveModel to mimic much of the behavior in ActiveRecord.
|
4
|
+
|
5
|
+
=== Installation
|
6
|
+
|
7
|
+
Add the following to your Gemfile:
|
8
|
+
|
9
|
+
gem 'cassandra_object_rails'
|
10
|
+
|
11
|
+
=== Defining Models
|
12
|
+
|
13
|
+
class Widget < CassandraObject::Base
|
14
|
+
string :name
|
15
|
+
string :description
|
16
|
+
integer :price
|
17
|
+
array :colors, unique: true
|
18
|
+
|
19
|
+
validates :name, presence: :true
|
20
|
+
|
21
|
+
before_create do
|
22
|
+
self.description = "#{name} is the best product ever"
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
=== Connecting to the Server
|
27
|
+
|
28
|
+
CassandraObject::Base.config = {
|
29
|
+
keyspace: 'my_app_development',
|
30
|
+
servers: '127.0.0.1:9160',
|
31
|
+
thrift: {
|
32
|
+
timeout: 20,
|
33
|
+
retries: 2
|
34
|
+
}
|
35
|
+
}
|
36
|
+
|
37
|
+
=== Connecting your rails application with Cassandra
|
38
|
+
|
39
|
+
in your config/cassandra.yml
|
40
|
+
|
41
|
+
development:
|
42
|
+
keyspace: 'my_app_development'
|
43
|
+
servers: '127.0.0.1:9160'
|
44
|
+
|
45
|
+
test:
|
46
|
+
keyspace: 'my_app_development'
|
47
|
+
servers: '127.0.0.1:9160'
|
48
|
+
|
49
|
+
production:
|
50
|
+
keyspace: 'my_app_development'
|
51
|
+
servers: '127.0.0.1:9160'
|
52
|
+
|
53
|
+
|
54
|
+
=== Creating and updating records
|
55
|
+
|
56
|
+
Cassandra Object has equivalent methods as ActiveRecord:
|
57
|
+
|
58
|
+
widget = Widget.new
|
59
|
+
widget.valid?
|
60
|
+
widget = Widget.create(name: 'Acme', price: 100)
|
61
|
+
widget.update_attribute(:price, 1200)
|
62
|
+
widget.update_attributes(price: 1200, name: 'Acme Corporation')
|
63
|
+
widget.attributes = {price: 300}
|
64
|
+
widget.price_was
|
65
|
+
widget.save
|
66
|
+
widget.save!
|
67
|
+
|
68
|
+
=== Finding records
|
69
|
+
|
70
|
+
widget = Widget.find(uuid)
|
71
|
+
widget = Widget.first
|
72
|
+
widgets = Widget.all
|
73
|
+
Widget.find_each do |widget|
|
74
|
+
...
|
75
|
+
end
|
76
|
+
|
77
|
+
=== Query
|
78
|
+
|
79
|
+
Some lightweight scoping features are available:
|
80
|
+
|
81
|
+
Widget.where('color' => 'red')
|
82
|
+
Widget.select(['name', 'color'])
|
83
|
+
Widget.limit(10)
|
84
|
+
|
85
|
+
=== Keyspace
|
86
|
+
|
87
|
+
Creating cassandra keyspace defined on cassandra.yml
|
88
|
+
|
89
|
+
rake cassandra:create
|
90
|
+
|
91
|
+
Droping cassandra keyspace
|
92
|
+
|
93
|
+
rake cassandra:drop
|
94
|
+
|
95
|
+
=== Adding column family
|
96
|
+
|
97
|
+
CassandraObject::Schema.create_column_family 'Widgets'
|
data/Rakefile
ADDED
@@ -0,0 +1,26 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
|
3
|
+
Gem::Specification.new do |s|
|
4
|
+
s.name = 'cassandra_object_rails'
|
5
|
+
s.version = '0.0.1'
|
6
|
+
s.description = 'Cassandra ActiveModel'
|
7
|
+
s.summary = 'Cassandra ActiveModel'
|
8
|
+
s.authors = ["Lucas Allan Amorim"]
|
9
|
+
s.email = 'lucas.allan@gmail.com'
|
10
|
+
s.homepage = 'http://github.com/lucasallan/cassandra_object'
|
11
|
+
|
12
|
+
s.required_ruby_version = '>= 1.9.2'
|
13
|
+
s.required_rubygems_version = '>= 1.3.5'
|
14
|
+
|
15
|
+
s.extra_rdoc_files = ["README.rdoc"]
|
16
|
+
s.files = `git ls-files`.split("\n")
|
17
|
+
s.test_files = `git ls-files -- {test}/*`.split("\n")
|
18
|
+
s.require_paths = ['lib']
|
19
|
+
|
20
|
+
s.add_runtime_dependency('activemodel', '>= 3.0')
|
21
|
+
s.add_runtime_dependency('cassandra-cql')
|
22
|
+
s.add_runtime_dependency('thrift_client', '~> 0.9.2')
|
23
|
+
s.add_runtime_dependency('thin')
|
24
|
+
|
25
|
+
s.add_development_dependency('bundler')
|
26
|
+
end
|
@@ -0,0 +1,87 @@
|
|
1
|
+
module CassandraObject
|
2
|
+
module AttributeMethods
|
3
|
+
extend ActiveSupport::Concern
|
4
|
+
include ActiveModel::AttributeMethods
|
5
|
+
|
6
|
+
included do
|
7
|
+
if ActiveModel::VERSION::STRING < '3.2'
|
8
|
+
attribute_method_suffix("", "=")
|
9
|
+
else
|
10
|
+
attribute_method_suffix("=")
|
11
|
+
end
|
12
|
+
|
13
|
+
# (Alias for the protected read_attribute method).
|
14
|
+
def [](attr_name)
|
15
|
+
read_attribute(attr_name)
|
16
|
+
end
|
17
|
+
|
18
|
+
# Updates the attribute identified by <tt>attr_name</tt> with the specified +value+.
|
19
|
+
# (Alias for the protected write_attribute method).
|
20
|
+
def []=(attr_name, value)
|
21
|
+
write_attribute(attr_name, value)
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
module ClassMethods
|
26
|
+
def define_attribute_methods
|
27
|
+
return if attribute_methods_generated?
|
28
|
+
super(attribute_definitions.keys)
|
29
|
+
@attribute_methods_generated = true
|
30
|
+
end
|
31
|
+
|
32
|
+
def attribute_methods_generated?
|
33
|
+
@attribute_methods_generated ||= false
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
def write_attribute(name, value)
|
38
|
+
@attributes[name.to_s] = self.class.typecast_attribute(self, name, value)
|
39
|
+
end
|
40
|
+
|
41
|
+
def read_attribute(name)
|
42
|
+
@attributes[name.to_s]
|
43
|
+
end
|
44
|
+
|
45
|
+
def attribute_exists?(name)
|
46
|
+
@attributes.key?(name.to_s)
|
47
|
+
end
|
48
|
+
|
49
|
+
def attributes
|
50
|
+
Hash[@attributes.map { |name, _| [name, read_attribute(name)] }]
|
51
|
+
end
|
52
|
+
|
53
|
+
def attributes=(attributes)
|
54
|
+
attributes.each do |(name, value)|
|
55
|
+
send("#{name}=", value)
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
def method_missing(method_id, *args, &block)
|
60
|
+
if !self.class.attribute_methods_generated?
|
61
|
+
self.class.define_attribute_methods
|
62
|
+
send(method_id, *args, &block)
|
63
|
+
else
|
64
|
+
super
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
def respond_to?(*args)
|
69
|
+
self.class.define_attribute_methods unless self.class.attribute_methods_generated?
|
70
|
+
super
|
71
|
+
end
|
72
|
+
|
73
|
+
protected
|
74
|
+
def attribute_method?(name)
|
75
|
+
!!attribute_definitions[name.to_sym]
|
76
|
+
end
|
77
|
+
|
78
|
+
private
|
79
|
+
def attribute(name)
|
80
|
+
read_attribute(name)
|
81
|
+
end
|
82
|
+
|
83
|
+
def attribute=(name, value)
|
84
|
+
write_attribute(name, value)
|
85
|
+
end
|
86
|
+
end
|
87
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
module CassandraObject
|
2
|
+
module AttributeMethods
|
3
|
+
class Definition
|
4
|
+
attr_reader :name, :coder
|
5
|
+
def initialize(name, coder, options)
|
6
|
+
@name = name.to_s
|
7
|
+
@coder = coder.new(options)
|
8
|
+
end
|
9
|
+
|
10
|
+
def instantiate(record, value)
|
11
|
+
value = value.nil? ? coder.default : value
|
12
|
+
return if value.nil?
|
13
|
+
|
14
|
+
value = value.kind_of?(String) ? coder.decode(value) : value
|
15
|
+
coder.wrap(record, name, value)
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,44 @@
|
|
1
|
+
module CassandraObject
|
2
|
+
module AttributeMethods
|
3
|
+
module Dirty
|
4
|
+
extend ActiveSupport::Concern
|
5
|
+
include ActiveModel::Dirty
|
6
|
+
|
7
|
+
# Attempts to +save+ the record and clears changed attributes if successful.
|
8
|
+
def save(*) #:nodoc:
|
9
|
+
if status = super
|
10
|
+
@previously_changed = changes
|
11
|
+
@changed_attributes.clear
|
12
|
+
end
|
13
|
+
status
|
14
|
+
end
|
15
|
+
|
16
|
+
# Attempts to <tt>save!</tt> the record and clears changed attributes if successful.
|
17
|
+
def save!(*) #:nodoc:
|
18
|
+
super.tap do
|
19
|
+
@previously_changed = changes
|
20
|
+
@changed_attributes.clear
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
# <tt>reload</tt> the record and clears changed attributes.
|
25
|
+
def reload
|
26
|
+
super.tap do
|
27
|
+
@previously_changed.try :clear
|
28
|
+
@changed_attributes.try :clear
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
def write_attribute(name, value)
|
33
|
+
name = name.to_s
|
34
|
+
old = read_attribute(name)
|
35
|
+
|
36
|
+
super
|
37
|
+
|
38
|
+
unless attribute_changed?(name) || old == read_attribute(name)
|
39
|
+
changed_attributes[name] = old
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
module CassandraObject
|
2
|
+
module AttributeMethods
|
3
|
+
module PrimaryKey
|
4
|
+
extend ActiveSupport::Concern
|
5
|
+
|
6
|
+
module ClassMethods
|
7
|
+
def primary_key
|
8
|
+
'id'
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
def id
|
13
|
+
@id ||= self.class._generate_key(self)
|
14
|
+
end
|
15
|
+
|
16
|
+
def id=(id)
|
17
|
+
@id = id
|
18
|
+
end
|
19
|
+
|
20
|
+
def attributes
|
21
|
+
super.update(self.class.primary_key => id)
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,59 @@
|
|
1
|
+
module CassandraObject
|
2
|
+
module AttributeMethods
|
3
|
+
module Typecasting
|
4
|
+
extend ActiveSupport::Concern
|
5
|
+
|
6
|
+
included do
|
7
|
+
class_attribute :attribute_definitions
|
8
|
+
self.attribute_definitions = {}
|
9
|
+
|
10
|
+
%w(array boolean date float integer json string time).each do |type|
|
11
|
+
instance_eval <<-EOV, __FILE__, __LINE__ + 1
|
12
|
+
def #{type}(*args)
|
13
|
+
options = args.extract_options!
|
14
|
+
args.each do |name|
|
15
|
+
attribute(name, options.merge(:type => :#{type}))
|
16
|
+
end
|
17
|
+
end
|
18
|
+
EOV
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
module ClassMethods
|
23
|
+
def inherited(child)
|
24
|
+
super
|
25
|
+
child.attribute_definitions = attribute_definitions.dup
|
26
|
+
end
|
27
|
+
|
28
|
+
#
|
29
|
+
# attribute :name, type: :string
|
30
|
+
# attribute :ammo, type: Ammo, coder: AmmoCodec
|
31
|
+
#
|
32
|
+
def attribute(name, options)
|
33
|
+
type = options[:type]
|
34
|
+
coder = options[:coder]
|
35
|
+
|
36
|
+
if type.is_a?(Symbol)
|
37
|
+
coder = CassandraObject::Type.get_coder(type) || (raise "Unknown type #{type}")
|
38
|
+
elsif coder.nil?
|
39
|
+
raise "Must supply a :coder for #{name}"
|
40
|
+
end
|
41
|
+
|
42
|
+
attribute_definitions[name.to_sym] = AttributeMethods::Definition.new(name, coder, options)
|
43
|
+
end
|
44
|
+
|
45
|
+
def typecast_attribute(record, name, value)
|
46
|
+
if attribute_definition = attribute_definitions[name.to_sym]
|
47
|
+
attribute_definition.instantiate(record, value)
|
48
|
+
else
|
49
|
+
raise NoMethodError, "Unknown attribute #{name.inspect}"
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
def coder_for(attribute)
|
54
|
+
attribute_definitions[attribute.to_sym].coder
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|