wcc-arena 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +18 -0
- data/.rspec +2 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +22 -0
- data/README.md +71 -0
- data/Rakefile +45 -0
- data/lib/wcc/arena.rb +15 -0
- data/lib/wcc/arena/address.rb +21 -0
- data/lib/wcc/arena/config.rb +39 -0
- data/lib/wcc/arena/email.rb +10 -0
- data/lib/wcc/arena/group.rb +29 -0
- data/lib/wcc/arena/group_member.rb +35 -0
- data/lib/wcc/arena/group_member_query.rb +32 -0
- data/lib/wcc/arena/group_query.rb +36 -0
- data/lib/wcc/arena/mappers.rb +6 -0
- data/lib/wcc/arena/mappers/xml.rb +131 -0
- data/lib/wcc/arena/modify_result.rb +10 -0
- data/lib/wcc/arena/person.rb +67 -0
- data/lib/wcc/arena/person_attribute.rb +12 -0
- data/lib/wcc/arena/person_attribute_group.rb +12 -0
- data/lib/wcc/arena/person_attribute_query.rb +29 -0
- data/lib/wcc/arena/person_query.rb +69 -0
- data/lib/wcc/arena/phone.rb +15 -0
- data/lib/wcc/arena/profile.rb +35 -0
- data/lib/wcc/arena/profile_member.rb +17 -0
- data/lib/wcc/arena/profile_member_query.rb +31 -0
- data/lib/wcc/arena/profile_member_save.rb +100 -0
- data/lib/wcc/arena/profile_query.rb +56 -0
- data/lib/wcc/arena/response.rb +22 -0
- data/lib/wcc/arena/session.rb +103 -0
- data/lib/wcc/arena/signed_path.rb +36 -0
- data/lib/wcc/arena/version.rb +5 -0
- data/spec/fixtures/group_member_list.xml +138 -0
- data/spec/fixtures/modify_result_failure.xml +6 -0
- data/spec/fixtures/modify_result_success.xml +6 -0
- data/spec/fixtures/person.xml +89 -0
- data/spec/fixtures/person_attribute_list.xml +59 -0
- data/spec/fixtures/person_group_list.xml +52 -0
- data/spec/fixtures/person_list.xml +75 -0
- data/spec/fixtures/profile_list.xml +68 -0
- data/spec/fixtures/profile_member_list.xml +41 -0
- data/spec/fixtures/profile_member_save.xml +14 -0
- data/spec/spec_helper.rb +19 -0
- data/spec/support/fixtures_helpers.rb +15 -0
- data/spec/wcc/arena/config_spec.rb +46 -0
- data/spec/wcc/arena/group_member_query_spec.rb +56 -0
- data/spec/wcc/arena/group_member_spec.rb +40 -0
- data/spec/wcc/arena/group_query_spec.rb +56 -0
- data/spec/wcc/arena/group_spec.rb +21 -0
- data/spec/wcc/arena/mappers/xml_spec.rb +246 -0
- data/spec/wcc/arena/modify_result_spec.rb +33 -0
- data/spec/wcc/arena/person_attribute_group_spec.rb +10 -0
- data/spec/wcc/arena/person_attribute_query_spec.rb +53 -0
- data/spec/wcc/arena/person_attribute_spec.rb +10 -0
- data/spec/wcc/arena/person_query_spec.rb +87 -0
- data/spec/wcc/arena/person_spec.rb +58 -0
- data/spec/wcc/arena/profile_member_query_spec.rb +56 -0
- data/spec/wcc/arena/profile_member_save_spec.rb +152 -0
- data/spec/wcc/arena/profile_member_spec.rb +39 -0
- data/spec/wcc/arena/profile_query_spec.rb +77 -0
- data/spec/wcc/arena/profile_spec.rb +33 -0
- data/spec/wcc/arena/response_spec.rb +43 -0
- data/spec/wcc/arena/session_spec.rb +196 -0
- data/spec/wcc/arena/signed_path_spec.rb +81 -0
- data/wcc-arena.gemspec +27 -0
- metadata +236 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 847a7b9b46ead985eb00221fb3ce685215671746
|
4
|
+
data.tar.gz: 7ce4cea280b3de3c7761e64619d5d3af2083caab
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 23dda6c3fc79b84e9934f985c73ebc1d64dff57244b5780c24e05c8bbebb0d0a995dbf955398f5f941afc9dc7f9d1898b408d80b18cd0e3ee3cbd3861fe81d72
|
7
|
+
data.tar.gz: 5b504562dd6e74c74fec426714500952a07a6410facf94f41765df9b7753487502aebe295efa6622daf75f1cb7154b2ee46e240079bf1934c00f8988e8d35839
|
data/.gitignore
ADDED
data/.rspec
ADDED
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2014 Watermark Community Church
|
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,71 @@
|
|
1
|
+
# WCC::Arena
|
2
|
+
|
3
|
+
This gem provides wrappers to the Arena church management system's API.
|
4
|
+
This is an early version of the library, and has had limited testing in
|
5
|
+
real world environments. Use at your own risk!
|
6
|
+
|
7
|
+
There are also bound to be a few things that are specific to our
|
8
|
+
configuration and version of Arena. This isn't intentional and we
|
9
|
+
consider that a bug that we would like to fix. We would love for this to
|
10
|
+
be a fully featured way to interact with Arena's API.
|
11
|
+
|
12
|
+
## Installation
|
13
|
+
|
14
|
+
Add this line to your application's Gemfile:
|
15
|
+
|
16
|
+
gem 'wcc-arena'
|
17
|
+
|
18
|
+
And then execute:
|
19
|
+
|
20
|
+
$ bundle
|
21
|
+
|
22
|
+
Or install it yourself as:
|
23
|
+
|
24
|
+
$ gem install wcc-arena
|
25
|
+
|
26
|
+
## Configuration
|
27
|
+
|
28
|
+
You can configure the wcc-arena gem using the `WCC::Arena.configure`
|
29
|
+
method.
|
30
|
+
|
31
|
+
Here is an example configuration block:
|
32
|
+
|
33
|
+
```ruby
|
34
|
+
WCC::Arena.configure do |arena|
|
35
|
+
arena.username = 'username'
|
36
|
+
arena.password = 'password'
|
37
|
+
arena.api_key = 'api_key'
|
38
|
+
arena.api_secret = 'api_secret'
|
39
|
+
arena.api_url = 'https://arena-domain/api.svc/'
|
40
|
+
end
|
41
|
+
```end
|
42
|
+
|
43
|
+
## Usage
|
44
|
+
|
45
|
+
The library is currently a very thin layer over the Arena API. We plan
|
46
|
+
to add a higher level interface layer that provides a better experience
|
47
|
+
for the most common use cases.
|
48
|
+
|
49
|
+
The library consists of Query classes and Mapper classes. The Query
|
50
|
+
classes handle calling the respective services and the Mapper classes
|
51
|
+
handle binding the XML to Ruby objects. For full details on all
|
52
|
+
available endpoints please see the code. Below are a few examples of
|
53
|
+
some common queries.
|
54
|
+
|
55
|
+
```ruby
|
56
|
+
query = WCC::Arena::PersonQuery.new.where(first_name: "Travis")
|
57
|
+
people = query.call
|
58
|
+
people.each do |person|
|
59
|
+
puts person.full_name
|
60
|
+
end
|
61
|
+
```
|
62
|
+
This will print the full names of all person records with the first name
|
63
|
+
"Travis".
|
64
|
+
|
65
|
+
## Contributing
|
66
|
+
|
67
|
+
1. Fork it
|
68
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
69
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
70
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
71
|
+
5. Create new Pull Request
|
data/Rakefile
ADDED
@@ -0,0 +1,45 @@
|
|
1
|
+
require "bundler/gem_tasks"
|
2
|
+
require "json"
|
3
|
+
|
4
|
+
PROJECT_PATH = File.dirname(__FILE__)
|
5
|
+
LIB_PATH = File.join(PROJECT_PATH, "lib")
|
6
|
+
CREDENTIALS_PATH = File.join(PROJECT_PATH, ".arena-creds")
|
7
|
+
|
8
|
+
task :default => :test
|
9
|
+
|
10
|
+
desc 'set load path and require the gem'
|
11
|
+
task :environment do
|
12
|
+
$LOAD_PATH.unshift(LIB_PATH)
|
13
|
+
require 'wcc/arena'
|
14
|
+
end
|
15
|
+
|
16
|
+
desc 'run test examples'
|
17
|
+
task :test do
|
18
|
+
exec 'rspec .'
|
19
|
+
end
|
20
|
+
|
21
|
+
desc 'open an IRB session with environment loaded'
|
22
|
+
task :irb => :environment do
|
23
|
+
require 'irb'
|
24
|
+
ARGV.clear
|
25
|
+
IRB.start
|
26
|
+
end
|
27
|
+
|
28
|
+
desc 'point the library at the instance of Arena described in .arena-creds and launch irb'
|
29
|
+
task :arena => :environment do
|
30
|
+
creds = JSON.parse(File.open(CREDENTIALS_PATH).read)
|
31
|
+
WCC::Arena.configure do |arena|
|
32
|
+
arena.username = creds['username']
|
33
|
+
arena.password = creds['password']
|
34
|
+
arena.api_key = creds['api_key']
|
35
|
+
arena.api_secret = creds['api_secret']
|
36
|
+
arena.api_url = creds['api_url']
|
37
|
+
end
|
38
|
+
$session = WCC::Arena::Session.new(
|
39
|
+
username: WCC::Arena.config.username,
|
40
|
+
password: WCC::Arena.config.password,
|
41
|
+
api_key: WCC::Arena.config.api_key,
|
42
|
+
api_secret: WCC::Arena.config.api_secret,
|
43
|
+
)
|
44
|
+
Rake::Task['irb'].invoke
|
45
|
+
end
|
data/lib/wcc/arena.rb
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
require "wcc/arena/version"
|
2
|
+
|
3
|
+
require 'faraday'
|
4
|
+
require 'nokogiri'
|
5
|
+
|
6
|
+
require "wcc/arena/config"
|
7
|
+
require "wcc/arena/mappers"
|
8
|
+
require 'wcc/arena/modify_result'
|
9
|
+
require "wcc/arena/response"
|
10
|
+
require "wcc/arena/session"
|
11
|
+
require "wcc/arena/signed_path"
|
12
|
+
|
13
|
+
require "wcc/arena/group"
|
14
|
+
require "wcc/arena/person"
|
15
|
+
require "wcc/arena/profile"
|
@@ -0,0 +1,21 @@
|
|
1
|
+
module WCC::Arena
|
2
|
+
|
3
|
+
class Address
|
4
|
+
include WCC::Arena::Mappers::XML
|
5
|
+
|
6
|
+
attribute :id, xpath: "AddressID", type: :integer
|
7
|
+
attribute :type_id, xpath: "AddressTypeID", type: :integer
|
8
|
+
attribute :type_value, xpath: "AddressTypeValue"
|
9
|
+
attribute :city, xpath: "City"
|
10
|
+
attribute :country, xpath: "Country"
|
11
|
+
attribute :latitude, xpath: "Latitude"
|
12
|
+
attribute :longitude, xpath: "Longitude"
|
13
|
+
attribute :postal_code, xpath: "PostalCode"
|
14
|
+
attribute :primary, xpath: "Primary", type: :boolean
|
15
|
+
attribute :state, xpath: "State"
|
16
|
+
attribute :street1, xpath: "StreetLine1"
|
17
|
+
attribute :street2, xpath: "StreetLine2"
|
18
|
+
|
19
|
+
end
|
20
|
+
|
21
|
+
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
module WCC::Arena
|
2
|
+
class Config
|
3
|
+
attr_accessor :username, :password, :api_key, :api_secret
|
4
|
+
attr_accessor :api_url
|
5
|
+
attr_accessor :logger, :connection
|
6
|
+
|
7
|
+
def connection
|
8
|
+
@connection ||= default_connection
|
9
|
+
end
|
10
|
+
|
11
|
+
def session
|
12
|
+
@session ||= WCC::Arena::Session.new(
|
13
|
+
connection: connection,
|
14
|
+
username: username,
|
15
|
+
password: password,
|
16
|
+
api_key: api_key,
|
17
|
+
api_secret: api_secret
|
18
|
+
)
|
19
|
+
end
|
20
|
+
|
21
|
+
private
|
22
|
+
|
23
|
+
def default_connection
|
24
|
+
Faraday.new(url: api_url) do |faraday|
|
25
|
+
faraday.request :url_encoded
|
26
|
+
faraday.response :logger
|
27
|
+
faraday.adapter Faraday.default_adapter
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
def self.config
|
33
|
+
@config ||= Config.new
|
34
|
+
end
|
35
|
+
|
36
|
+
def self.configure
|
37
|
+
yield config
|
38
|
+
end
|
39
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
require 'wcc/arena/group_query'
|
2
|
+
|
3
|
+
require 'wcc/arena/address'
|
4
|
+
require 'wcc/arena/group_member'
|
5
|
+
|
6
|
+
module WCC::Arena
|
7
|
+
class Group
|
8
|
+
include WCC::Arena::Mappers::XML
|
9
|
+
|
10
|
+
attribute :id, xpath: "GroupID", type: :integer
|
11
|
+
attribute :guid, xpath: "Guid"
|
12
|
+
|
13
|
+
attribute :name, xpath: "Name"
|
14
|
+
attribute :active, xpath: "Active", type: :boolean
|
15
|
+
attribute :area_name, xpath: "AreaName"
|
16
|
+
attribute :area_id, xpath: "AreaID", type: :integer
|
17
|
+
attribute :type, xpath: "GroupTypeValue"
|
18
|
+
attribute :type_id, xpath: "GroupTypeID", type: :integer
|
19
|
+
attribute :leader_id, xpath: "LeaderID", type: :integer
|
20
|
+
|
21
|
+
has_one :address, xpath: "TargetLocation", klass: Address
|
22
|
+
|
23
|
+
alias :active? :active
|
24
|
+
|
25
|
+
def members
|
26
|
+
@members ||= GroupMemberQuery.new(group_id: id).()
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
require 'wcc/arena/group_member_query'
|
2
|
+
|
3
|
+
require 'wcc/arena/person'
|
4
|
+
|
5
|
+
module WCC::Arena
|
6
|
+
|
7
|
+
class GroupMember
|
8
|
+
include WCC::Arena::Mappers::XML
|
9
|
+
|
10
|
+
attribute :group_id, xpath: "GroupID", type: :integer
|
11
|
+
attribute :person_id, xpath: "PersonID", type: :integer
|
12
|
+
|
13
|
+
attribute :active, xpath: "Active", type: :boolean
|
14
|
+
attribute :joined_at, xpath: "DateJoined", type: :time
|
15
|
+
attribute :role, xpath: "RoleValue"
|
16
|
+
attribute :role_id, xpath: "RoleID", type: :integer
|
17
|
+
attribute :person_link, xpath: "PersonLink"
|
18
|
+
|
19
|
+
has_one :person, xpath: "PersonInformation", klass: Person
|
20
|
+
|
21
|
+
def person_guid
|
22
|
+
person_link.split("/").last
|
23
|
+
end
|
24
|
+
|
25
|
+
def full_name
|
26
|
+
person.full_name ||
|
27
|
+
[
|
28
|
+
person.first_name,
|
29
|
+
person.last_name
|
30
|
+
].join(" ")
|
31
|
+
end
|
32
|
+
|
33
|
+
end
|
34
|
+
|
35
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
module WCC::Arena
|
2
|
+
|
3
|
+
class GroupMemberQuery
|
4
|
+
attr_reader :session
|
5
|
+
attr_reader :group_id
|
6
|
+
|
7
|
+
def initialize(args={})
|
8
|
+
@session = args.fetch(:session) { WCC::Arena.config.session }
|
9
|
+
@group_id = args.fetch(:group_id)
|
10
|
+
end
|
11
|
+
|
12
|
+
def call
|
13
|
+
members_xml.collect do |member_xml|
|
14
|
+
GroupMember.new(member_xml)
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
private
|
19
|
+
|
20
|
+
def members_xml
|
21
|
+
query_response.xml.root.xpath("Members/GroupMember")
|
22
|
+
end
|
23
|
+
|
24
|
+
def query_response
|
25
|
+
@response ||= session.get(
|
26
|
+
"group/#{group_id}/member/list"
|
27
|
+
)
|
28
|
+
end
|
29
|
+
|
30
|
+
end
|
31
|
+
|
32
|
+
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
module WCC::Arena
|
2
|
+
|
3
|
+
class GroupQuery
|
4
|
+
attr_reader :session
|
5
|
+
attr_reader :person_id
|
6
|
+
attr_reader :category_id
|
7
|
+
|
8
|
+
def initialize(args={})
|
9
|
+
@session = args.fetch(:session) { WCC::Arena.config.session }
|
10
|
+
@person_id = args.fetch(:person_id)
|
11
|
+
@category_id = args.fetch(:category_id)
|
12
|
+
end
|
13
|
+
|
14
|
+
def call
|
15
|
+
response_groups_xml.collect do |person_xml|
|
16
|
+
Group.new(person_xml)
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
private
|
21
|
+
|
22
|
+
def response_groups_xml
|
23
|
+
query_response.xml.root.xpath("Groups/Group")
|
24
|
+
end
|
25
|
+
|
26
|
+
def query_response
|
27
|
+
@response ||= session.get(
|
28
|
+
"person/#{person_id}/group/list",
|
29
|
+
categoryid: category_id
|
30
|
+
)
|
31
|
+
end
|
32
|
+
|
33
|
+
|
34
|
+
end
|
35
|
+
|
36
|
+
end
|
@@ -0,0 +1,131 @@
|
|
1
|
+
require 'date'
|
2
|
+
require 'time'
|
3
|
+
|
4
|
+
module WCC::Arena::Mappers
|
5
|
+
|
6
|
+
module XML
|
7
|
+
|
8
|
+
attr_reader :document
|
9
|
+
|
10
|
+
def initialize(document)
|
11
|
+
@document = document
|
12
|
+
end
|
13
|
+
|
14
|
+
def [](attribute)
|
15
|
+
if self.class.attributes[attribute]
|
16
|
+
load_attribute(attribute)
|
17
|
+
else
|
18
|
+
raise KeyError, "Attribute #{attribute} is not defined"
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
def attributes
|
23
|
+
self.class.attributes.each_with_object({}) do |(name, options), hash|
|
24
|
+
hash[name] = self[name]
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
def inspect
|
29
|
+
"<#{self.class.name} " \
|
30
|
+
"#{attributes.collect { |(name, value)| [name, value.inspect].join("=") }.join(" ")}>"
|
31
|
+
end
|
32
|
+
|
33
|
+
def load_association(name)
|
34
|
+
if config = self.class.associations[name]
|
35
|
+
list = document.xpath(config[:xpath]).collect do |node|
|
36
|
+
config[:klass].new(node)
|
37
|
+
end
|
38
|
+
case config[:type]
|
39
|
+
when :many
|
40
|
+
list
|
41
|
+
when :one
|
42
|
+
list.first
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
private :load_association
|
47
|
+
|
48
|
+
def load_attribute(attribute)
|
49
|
+
config = self.class.attributes[attribute]
|
50
|
+
node = document.xpath(config[:xpath])
|
51
|
+
cast_attribute(node.text, config[:type])
|
52
|
+
end
|
53
|
+
|
54
|
+
def cast_attribute(text, type)
|
55
|
+
return nil if text.empty?
|
56
|
+
|
57
|
+
case type
|
58
|
+
when :integer
|
59
|
+
Integer(text)
|
60
|
+
when :date
|
61
|
+
Date.strptime(text.split("T").first, "%Y-%m-%d")
|
62
|
+
when :time
|
63
|
+
Time.parse(text)
|
64
|
+
when :boolean
|
65
|
+
text.downcase == "true"
|
66
|
+
else
|
67
|
+
text
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
module ClassMethods
|
72
|
+
|
73
|
+
def attribute(name, options)
|
74
|
+
options.fetch(:xpath) {
|
75
|
+
raise ArgumentError, ":xpath is a required argument to the `attribute' method"
|
76
|
+
}
|
77
|
+
attributes[name] = options.freeze
|
78
|
+
define_method(name) { self[name] }
|
79
|
+
end
|
80
|
+
|
81
|
+
def attributes
|
82
|
+
@attributes ||= {}
|
83
|
+
end
|
84
|
+
|
85
|
+
def associations
|
86
|
+
@associations ||= {}
|
87
|
+
end
|
88
|
+
|
89
|
+
def has_one(name, options)
|
90
|
+
add_association(name, options.merge(type: :one)) do
|
91
|
+
@association_cache ||= {}
|
92
|
+
@association_cache[name] ||= load_association(name)
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
96
|
+
def has_many(name, options)
|
97
|
+
add_association(name, options.merge(type: :many)) do
|
98
|
+
@association_cache ||= {}
|
99
|
+
@association_cache[name] ||= load_association(name)
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
103
|
+
def add_association(name, options, &block)
|
104
|
+
options.fetch(:xpath) {
|
105
|
+
raise ArgumentError, ":xpath is a required argument"
|
106
|
+
}
|
107
|
+
options.fetch(:klass) {
|
108
|
+
raise ArgumentError, ":klass is a required argument"
|
109
|
+
}
|
110
|
+
options.fetch(:type) {
|
111
|
+
raise ArgumentError, ":type is a required argument"
|
112
|
+
}
|
113
|
+
associations[name] = options.freeze
|
114
|
+
define_method(name, &block) if block_given?
|
115
|
+
end
|
116
|
+
|
117
|
+
def inherited(subclass)
|
118
|
+
super
|
119
|
+
subclass.instance_variable_set(:@attributes, attributes.dup)
|
120
|
+
subclass.instance_variable_set(:@associations, associations.dup)
|
121
|
+
end
|
122
|
+
|
123
|
+
end
|
124
|
+
|
125
|
+
def self.included(receiver)
|
126
|
+
receiver.extend ClassMethods
|
127
|
+
end
|
128
|
+
|
129
|
+
end
|
130
|
+
|
131
|
+
end
|