has_dynamic_columns 0.1.1 → 0.2.0
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 +4 -4
- data/README.md +153 -4
- data/bin/console +15 -0
- data/bin/setup +7 -0
- data/has_dynamic_columns.gemspec +1 -1
- data/lib/has_dynamic_columns.rb +12 -301
- data/lib/has_dynamic_columns/active_record.rb +12 -0
- data/lib/has_dynamic_columns/active_record/query_methods.rb +231 -0
- data/lib/has_dynamic_columns/active_record/relation.rb +21 -0
- data/lib/has_dynamic_columns/active_record_relation.rb +105 -0
- data/lib/has_dynamic_columns/dynamic_column.rb +1 -1
- data/lib/has_dynamic_columns/dynamic_column_datum.rb +1 -1
- data/lib/has_dynamic_columns/dynamic_column_option.rb +1 -1
- data/lib/has_dynamic_columns/dynamic_column_validation.rb +1 -1
- data/lib/has_dynamic_columns/model.rb +10 -0
- data/lib/has_dynamic_columns/model/class_methods.rb +294 -0
- data/lib/has_dynamic_columns/model/instance_methods.rb +6 -0
- data/lib/has_dynamic_columns/version.rb +1 -1
- data/spec/has_dynamic_columns_spec.rb +76 -0
- data/spec/spec_helper.rb +5 -8
- metadata +18 -13
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 8e226dfbdf7a08adfe5c9fe89fd93704b94ce06c
|
4
|
+
data.tar.gz: f0a3a6de371ded59b17db4690d54093d2ab98d16
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 8dd05a3bd91dc8419c67506b463cb0c6741e1756901d9b4979202e4da4ea4c7a01b809de42d33a215f888ea490b458f5321ba2cad17291306d5e092db4bf0399
|
7
|
+
data.tar.gz: a543799ebbf31103a117652fe127a002e8fa6bbc00870e6c65c5eb54035f7c73af1eb2c8d81eed5eae3bddd3139cddb92c41da28fb749f39ee983511028da179
|
data/README.md
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
has_dynamic_columns
|
2
2
|
============
|
3
3
|
|
4
|
-
|
4
|
+
This plugin gives ActiveRecord models the ability to dynamically define collectable data based on ***has_many*** and ***belongs_to*** relationships.
|
5
5
|
|
6
6
|
Installation
|
7
7
|
============
|
8
8
|
|
9
9
|
```ruby
|
10
|
-
gem
|
10
|
+
gem "has_dynamic_columns"
|
11
11
|
```
|
12
12
|
|
13
13
|
The Active Record migration is required to create the has_dynamic_columns table. You can create that table by
|
@@ -19,6 +19,22 @@ running the following command:
|
|
19
19
|
Usage
|
20
20
|
============
|
21
21
|
|
22
|
+
has_dynamic_columns
|
23
|
+
|
24
|
+
- as:
|
25
|
+
- the setter/getter method
|
26
|
+
- field_scope:
|
27
|
+
- **belongs_to** or **has_many** relationship
|
28
|
+
|
29
|
+
## **belongs_to** relationship
|
30
|
+
|
31
|
+
Our example is a data model where an **account** ***has_many*** **customers** and each **customer** ***has_many*** **customer_addresses**
|
32
|
+
|
33
|
+
Each customers collectable info is uniquely defined by the associated account.
|
34
|
+
|
35
|
+
Each customer addresses collectable info is defined by the associated customers account.
|
36
|
+
|
37
|
+
**Models**
|
22
38
|
```ruby
|
23
39
|
class Account < ActiveRecord::Base
|
24
40
|
has_many :customers
|
@@ -27,8 +43,7 @@ end
|
|
27
43
|
|
28
44
|
class Customer < ActiveRecord::Base
|
29
45
|
belongs_to :account
|
30
|
-
|
31
|
-
has_dynamic_columns field_scope: "account", as: "fields"
|
46
|
+
has_dynamic_columns field_scope: "account", as: "customer_fields"
|
32
47
|
end
|
33
48
|
|
34
49
|
class CustomerAddress < ActiveRecord::Base
|
@@ -37,3 +52,137 @@ class CustomerAddress < ActiveRecord::Base
|
|
37
52
|
end
|
38
53
|
```
|
39
54
|
|
55
|
+
**Setup**
|
56
|
+
```ruby
|
57
|
+
# ------------------------------------------------
|
58
|
+
# Create our first account
|
59
|
+
# ------------------------------------------------
|
60
|
+
account = Account.new(:name => "Account #1")
|
61
|
+
|
62
|
+
# Define a first_name field
|
63
|
+
account.activerecord_dynamic_columns.build(:dynamic_type => "Customer", :key => "first_name", :data_type => "string")
|
64
|
+
# Define a last_name field
|
65
|
+
account.activerecord_dynamic_columns.build(:dynamic_type => "Customer", :key => "last_name", :data_type => "string")
|
66
|
+
# Define a company field
|
67
|
+
account.activerecord_dynamic_columns.build(:dynamic_type => "Customer", :key => "company", :data_type => "string")
|
68
|
+
|
69
|
+
# save
|
70
|
+
account.save
|
71
|
+
|
72
|
+
# ------------------------------------------------
|
73
|
+
# Create our second account
|
74
|
+
# ------------------------------------------------
|
75
|
+
account = Account.new(:name => "Account #2")
|
76
|
+
|
77
|
+
# Define a first_name field
|
78
|
+
account.activerecord_dynamic_columns.build(:dynamic_type => "Customer", :key => "first_name", :data_type => "string")
|
79
|
+
# Define a last_name field
|
80
|
+
account.activerecord_dynamic_columns.build(:dynamic_type => "Customer", :key => "last_name", :data_type => "string")
|
81
|
+
# Define a country field
|
82
|
+
account.activerecord_dynamic_columns.build(:dynamic_type => "Customer", :key => "country", :data_type => "string")
|
83
|
+
|
84
|
+
# save
|
85
|
+
account.save
|
86
|
+
```
|
87
|
+
|
88
|
+
**Data**
|
89
|
+
```ruby
|
90
|
+
# Add a customer to our first account
|
91
|
+
account = Account.find(1)
|
92
|
+
customer = Customer.new(:account => account)
|
93
|
+
customer.customer_fields = {
|
94
|
+
"first_name" => "Butch",
|
95
|
+
"last_Name" => "Marshall",
|
96
|
+
"company" => "Aperture Science"
|
97
|
+
}
|
98
|
+
customer.save
|
99
|
+
|
100
|
+
# as_json
|
101
|
+
customer.as_json
|
102
|
+
# == { "id": 1, "account_id": 1, "customer_fields" => { "first_name" => "Butch", "last_Name" => "Marshall", "company" => "Aperture Science" } }
|
103
|
+
|
104
|
+
# Add a customer to our first account
|
105
|
+
account = Account.find(1)
|
106
|
+
customer = Customer.new(:account => account)
|
107
|
+
customer.customer_fields = {
|
108
|
+
"first_name" => "John",
|
109
|
+
"last_Name" => "Paterson",
|
110
|
+
"company" => "Aperture Science"
|
111
|
+
}
|
112
|
+
customer.save
|
113
|
+
|
114
|
+
# Add a customer to our second account
|
115
|
+
account = Account.find(2)
|
116
|
+
customer = Customer.new(:account => account)
|
117
|
+
customer.customer_fields = {
|
118
|
+
"first_name" => "Butch",
|
119
|
+
"last_Name" => "Marshall",
|
120
|
+
"country" => "Canada"
|
121
|
+
}
|
122
|
+
customer.save
|
123
|
+
|
124
|
+
# as_json
|
125
|
+
puts customer.as_json
|
126
|
+
# == { "id": 2, "account_id": 2, "customer_fields" => { "first_name" => "Butch", "last_Name" => "Marshall", "country" => "Canada" } }
|
127
|
+
```
|
128
|
+
|
129
|
+
**Searching**
|
130
|
+
```ruby
|
131
|
+
|
132
|
+
# ------------------------------------------------
|
133
|
+
# with_scope
|
134
|
+
# ------------------------------------------------
|
135
|
+
|
136
|
+
# ------------------------------------------------
|
137
|
+
# Find customers under the first account
|
138
|
+
# ------------------------------------------------
|
139
|
+
account = Account.find(1)
|
140
|
+
|
141
|
+
# 1 result
|
142
|
+
Customer.where.has_dynamic_scope({ :first_name => "Butch" }).with_scope(account)
|
143
|
+
|
144
|
+
# 1 result
|
145
|
+
Customer.where.has_dynamic_scope({ :first_name => "Butch", :company => "Aperture Science" }).with_scope(account)
|
146
|
+
|
147
|
+
# 0 results
|
148
|
+
Customer.where.has_dynamic_scope({ :first_name => "Butch", :company => "Blaaaaa" }).with_scope(account)
|
149
|
+
|
150
|
+
# 2 results
|
151
|
+
Customer.where.has_dynamic_scope({ :company => "Aperture Science" }).with_scope(account)
|
152
|
+
|
153
|
+
# ------------------------------------------------
|
154
|
+
# Find customers under the second account
|
155
|
+
# ------------------------------------------------
|
156
|
+
account = Account.find(2)
|
157
|
+
# 1 result
|
158
|
+
Customer.where.has_dynamic_scope({ :first_name => "Butch" }).with_scope(account)
|
159
|
+
|
160
|
+
# 1 result
|
161
|
+
Customer.where.has_dynamic_scope({ :first_name => "Butch", :country => "Canada" }).with_scope(account)
|
162
|
+
|
163
|
+
# 0 results
|
164
|
+
Customer.where.has_dynamic_scope({ :first_name => "Butch", :country => "Japan" }).with_scope(account)
|
165
|
+
```
|
166
|
+
|
167
|
+
# ------------------------------------------------
|
168
|
+
# without_scope
|
169
|
+
# ------------------------------------------------
|
170
|
+
|
171
|
+
# 6 results
|
172
|
+
# finds everyone named butch, no matter what account they're apart of
|
173
|
+
Customer.where.has_dynamic_scope({ :first_name => "Butch" }).without_scope
|
174
|
+
|
175
|
+
# ------------------------------------------------
|
176
|
+
# with Arel
|
177
|
+
# WARNING: compound conditionals such as Customer.arel_table[:first_Name].matches("B%").and(Customer.arel_table[:first_Name].eq("Canada")) are NOT currently supported
|
178
|
+
# ------------------------------------------------
|
179
|
+
|
180
|
+
# 6 matches
|
181
|
+
Customer.where.has_dynamic_scope(Customer.arel_table[:first_Name].matches("B%")).without_scope
|
182
|
+
|
183
|
+
# 1 match
|
184
|
+
Customer.where.has_dynamic_scope(Customer.arel_table[:first_Name].eq("Canada")).with_scope(Account.find(1))
|
185
|
+
|
186
|
+
## **has_many** relationship
|
187
|
+
|
188
|
+
TODO example.
|
data/bin/console
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require "bundler/setup"
|
4
|
+
require "active_record"
|
5
|
+
require "has_dynamic_columns"
|
6
|
+
|
7
|
+
# You can add fixtures and/or initialization code here to make experimenting
|
8
|
+
# with your gem easier. You can also use a different console, if you like.
|
9
|
+
|
10
|
+
# (If you use this, don't forget to add pry to your Gemfile!)
|
11
|
+
# require "pry"
|
12
|
+
# Pry.start
|
13
|
+
|
14
|
+
require "irb"
|
15
|
+
IRB.start
|
data/bin/setup
ADDED
data/has_dynamic_columns.gemspec
CHANGED
@@ -18,7 +18,7 @@ Gem::Specification.new do |spec|
|
|
18
18
|
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
19
19
|
spec.require_paths = ["lib"]
|
20
20
|
|
21
|
-
spec.add_dependency "activerecord",
|
21
|
+
spec.add_dependency "activerecord", "~> 4.2"
|
22
22
|
|
23
23
|
spec.add_development_dependency "bundler", "~> 1.7"
|
24
24
|
spec.add_development_dependency "rake", "~> 10.0"
|
data/lib/has_dynamic_columns.rb
CHANGED
@@ -1,5 +1,11 @@
|
|
1
1
|
require "active_support"
|
2
|
+
require 'active_support/dependencies'
|
3
|
+
require "active_record"
|
2
4
|
|
5
|
+
require "has_dynamic_columns/active_record/query_methods"
|
6
|
+
require "has_dynamic_columns/active_record/relation"
|
7
|
+
|
8
|
+
require "has_dynamic_columns/model"
|
3
9
|
require "has_dynamic_columns/version"
|
4
10
|
require "has_dynamic_columns/dynamic_column"
|
5
11
|
require "has_dynamic_columns/dynamic_column_option"
|
@@ -7,305 +13,6 @@ require "has_dynamic_columns/dynamic_column_validation"
|
|
7
13
|
require "has_dynamic_columns/dynamic_column_datum"
|
8
14
|
|
9
15
|
module HasDynamicColumns
|
10
|
-
module Model
|
11
|
-
def self.included(base)
|
12
|
-
base.send :extend, ClassMethods
|
13
|
-
end
|
14
|
-
|
15
|
-
module ClassMethods
|
16
|
-
def has_dynamic_columns(*args)
|
17
|
-
options = args.extract_options!
|
18
|
-
configuration = {
|
19
|
-
:as => "dynamic_columns",
|
20
|
-
:field_scope => nil,
|
21
|
-
}
|
22
|
-
configuration.update(options) if options.is_a?(Hash)
|
23
|
-
|
24
|
-
class_eval <<-EOV
|
25
|
-
alias_method :as_json_before_#{configuration[:as]}, :as_json
|
26
|
-
|
27
|
-
# Store all our configurations for usage later
|
28
|
-
@@has_dynamic_columns_configurations ||= []
|
29
|
-
@@has_dynamic_columns_configurations << #{configuration}
|
30
|
-
|
31
|
-
include ::HasDynamicColumns::Model::InstanceMethods
|
32
|
-
|
33
|
-
has_many :activerecord_dynamic_columns,
|
34
|
-
class_name: "HasDynamicColumns::DynamicColumn",
|
35
|
-
as: :field_scope
|
36
|
-
has_many :activerecord_dynamic_column_data,
|
37
|
-
class_name: "HasDynamicColumns::DynamicColumnDatum",
|
38
|
-
as: :owner,
|
39
|
-
autosave: true
|
40
|
-
|
41
|
-
# only add to attr_accessible
|
42
|
-
# if the class has some mass_assignment_protection
|
43
|
-
if defined?(accessible_attributes) and !accessible_attributes.blank?
|
44
|
-
#attr_accessible :#{configuration[:column]}
|
45
|
-
end
|
46
|
-
|
47
|
-
validate do |field_scope|
|
48
|
-
field_scope = self.get_#{configuration[:as]}_field_scope
|
49
|
-
|
50
|
-
if field_scope
|
51
|
-
# has_many association
|
52
|
-
if field_scope.respond_to?(:select) && field_scope.respond_to?(:collect)
|
53
|
-
|
54
|
-
# belongs_to association
|
55
|
-
else
|
56
|
-
# All the fields defined on the parent model
|
57
|
-
dynamic_columns = field_scope.send("activerecord_dynamic_columns")
|
58
|
-
|
59
|
-
self.send("activerecord_dynamic_column_data").each { |dynamic_column_datum|
|
60
|
-
# Collect all validation errors
|
61
|
-
validation_errors = []
|
62
|
-
|
63
|
-
if dynamic_column_datum.dynamic_column_option_id == -1
|
64
|
-
validation_errors << "invalid_option"
|
65
|
-
end
|
66
|
-
|
67
|
-
# Find the dynamic_column defined for this datum
|
68
|
-
dynamic_column = nil
|
69
|
-
dynamic_columns.each { |i|
|
70
|
-
if i == dynamic_column_datum.dynamic_column
|
71
|
-
dynamic_column = i
|
72
|
-
break
|
73
|
-
end
|
74
|
-
}
|
75
|
-
# We have a dynamic_column - validate
|
76
|
-
if dynamic_column
|
77
|
-
dynamic_column.dynamic_column_validations.each { |validation|
|
78
|
-
if !validation.is_valid?(dynamic_column_datum.value.to_s)
|
79
|
-
validation_errors << validation.error
|
80
|
-
end
|
81
|
-
}
|
82
|
-
else
|
83
|
-
# No field found - this is probably bad - should we throw an error?
|
84
|
-
validation_errors << "not_found"
|
85
|
-
end
|
86
|
-
|
87
|
-
# If any errors exist - add them
|
88
|
-
if validation_errors.length > 0
|
89
|
-
if dynamic_column.nil?
|
90
|
-
# TODO - fix from the has_many - need to fix validations
|
91
|
-
#errors.add(:dynamic_columns, { "unknown" => validation_errors })
|
92
|
-
else
|
93
|
-
errors.add(:dynamic_columns, { dynamic_column.key.to_s => validation_errors })
|
94
|
-
end
|
95
|
-
end
|
96
|
-
}
|
97
|
-
end
|
98
|
-
end
|
99
|
-
end
|
100
|
-
|
101
|
-
public
|
102
|
-
# Order by dynamic columns
|
103
|
-
def self.dynamic_order(field_scope, key, direction = :asc)
|
104
|
-
table = self.name.constantize.arel_table
|
105
|
-
column_table = HasDynamicColumns::DynamicColumn.arel_table.alias("dynamic_order_"+key.to_s)
|
106
|
-
column_datum_table = HasDynamicColumns::DynamicColumnDatum.arel_table.alias("dynamic_order_data_"+key.to_s)
|
107
|
-
|
108
|
-
field_scope_id = (!field_scope.nil?) ? field_scope.id : nil
|
109
|
-
field_scope_type = (!field_scope.nil?) ? field_scope.class.name.constantize.to_s : nil
|
110
|
-
dynamic_type = self.name.constantize.to_s
|
111
|
-
|
112
|
-
# Join on the column with the key
|
113
|
-
on_query = column_table[:key].eq(key)
|
114
|
-
if !field_scope_type.nil?
|
115
|
-
on_query = on_query.and(
|
116
|
-
column_table[:field_scope_type].eq(field_scope_type)
|
117
|
-
)
|
118
|
-
end
|
119
|
-
if !field_scope_id.nil?
|
120
|
-
on_query = on_query.and(
|
121
|
-
column_table[:field_scope_id].eq(field_scope_id)
|
122
|
-
)
|
123
|
-
end
|
124
|
-
|
125
|
-
column_table_join_on = column_table
|
126
|
-
.create_on(
|
127
|
-
on_query
|
128
|
-
)
|
129
|
-
|
130
|
-
column_table_join = table.create_join(column_table, column_table_join_on)
|
131
|
-
query = joins(column_table_join)
|
132
|
-
|
133
|
-
# Join on all the data with the provided key
|
134
|
-
column_table_datum_join_on = column_datum_table
|
135
|
-
.create_on(
|
136
|
-
column_datum_table[:owner_id].eq(table[:id]).and(
|
137
|
-
column_datum_table[:owner_type].eq(dynamic_type)
|
138
|
-
).and(
|
139
|
-
column_datum_table[:dynamic_column_id].eq(column_table[:id])
|
140
|
-
)
|
141
|
-
)
|
142
|
-
|
143
|
-
column_table_datum_join = table.create_join(column_datum_table, column_table_datum_join_on)
|
144
|
-
query = query.joins(column_table_datum_join)
|
145
|
-
|
146
|
-
# Order
|
147
|
-
query = query.order(column_datum_table[:value].send(direction))
|
148
|
-
|
149
|
-
# Group required - we have many rows
|
150
|
-
query = query.group(table[:id])
|
151
|
-
|
152
|
-
query
|
153
|
-
end
|
154
|
-
|
155
|
-
# Find by dynamic columns
|
156
|
-
def self.dynamic_where(*args)
|
157
|
-
field_scope = args[0].is_a?(Hash) ? nil : args[0]
|
158
|
-
options = args.extract_options!
|
159
|
-
|
160
|
-
field_scope_id = (!field_scope.nil?) ? field_scope.id : nil
|
161
|
-
field_scope_type = (!field_scope.nil?) ? field_scope.class.name.constantize.to_s : nil
|
162
|
-
dynamic_type = self.name.constantize.to_s
|
163
|
-
|
164
|
-
table = self.name.constantize.arel_table
|
165
|
-
query = nil
|
166
|
-
|
167
|
-
# Need to join on each of the keys we are performing where on
|
168
|
-
options.each { |key, value|
|
169
|
-
# Don't bother with empty values
|
170
|
-
next if value.to_s.empty?
|
171
|
-
|
172
|
-
column_table = HasDynamicColumns::DynamicColumn.arel_table.alias("dynamic_where_"+key.to_s)
|
173
|
-
column_datum_table = HasDynamicColumns::DynamicColumnDatum.arel_table.alias("dynamic_where_data_"+key.to_s)
|
174
|
-
|
175
|
-
# Join on the column with the key
|
176
|
-
on_query = column_table[:key].eq(key)
|
177
|
-
if !field_scope_type.nil?
|
178
|
-
on_query = on_query.and(
|
179
|
-
column_table[:field_scope_type].eq(field_scope_type)
|
180
|
-
)
|
181
|
-
end
|
182
|
-
if !field_scope_id.nil?
|
183
|
-
on_query = on_query.and(
|
184
|
-
column_table[:field_scope_id].eq(field_scope_id)
|
185
|
-
)
|
186
|
-
end
|
187
|
-
|
188
|
-
column_table_join_on = column_table
|
189
|
-
.create_on(
|
190
|
-
on_query
|
191
|
-
)
|
192
|
-
|
193
|
-
column_table_join = table.create_join(column_table, column_table_join_on)
|
194
|
-
query = (query.nil?)? joins(column_table_join) : query.joins(column_table_join)
|
195
|
-
|
196
|
-
# Join on all the data with the provided key
|
197
|
-
column_table_datum_join_on = column_datum_table
|
198
|
-
.create_on(
|
199
|
-
column_datum_table[:owner_id].eq(table[:id]).and(
|
200
|
-
column_datum_table[:owner_type].eq(dynamic_type)
|
201
|
-
).and(
|
202
|
-
column_datum_table[:dynamic_column_id].eq(column_table[:id])
|
203
|
-
).and(
|
204
|
-
column_datum_table[:value].matches("%"+value+"%")
|
205
|
-
)
|
206
|
-
)
|
207
|
-
|
208
|
-
column_table_datum_join = table.create_join(column_datum_table, column_table_datum_join_on)
|
209
|
-
query = query.joins(column_table_datum_join)
|
210
|
-
}
|
211
|
-
# Group required - we have many rows
|
212
|
-
query = (query.nil?)? group(table[:id]) : query.group(table[:id])
|
213
|
-
|
214
|
-
query
|
215
|
-
end
|
216
|
-
|
217
|
-
def as_json(*args)
|
218
|
-
json = super(*args)
|
219
|
-
options = args.extract_options!
|
220
|
-
|
221
|
-
@@has_dynamic_columns_configurations.each { |config|
|
222
|
-
if !options[:root].nil?
|
223
|
-
json[options[:root]][config[:as].to_s] = self.send(config[:as].to_s)
|
224
|
-
else
|
225
|
-
json[config[:as].to_s] = self.send(config[:as].to_s)
|
226
|
-
end
|
227
|
-
}
|
228
|
-
|
229
|
-
json
|
230
|
-
end
|
231
|
-
|
232
|
-
# Setter for dynamic field data
|
233
|
-
def #{configuration[:as]}=data
|
234
|
-
data.each_pair { |key, value|
|
235
|
-
# We dont play well with this key
|
236
|
-
if !self.storable_#{configuration[:as].to_s.singularize}_key?(key)
|
237
|
-
raise NoMethodError
|
238
|
-
end
|
239
|
-
dynamic_column = self.#{configuration[:as].to_s.singularize}_key_to_dynamic_column(key)
|
240
|
-
|
241
|
-
# We already have this key in database
|
242
|
-
if existing = self.activerecord_dynamic_column_data.select { |i| i.dynamic_column == dynamic_column }.first
|
243
|
-
existing.value = value
|
244
|
-
else
|
245
|
-
self.activerecord_dynamic_column_data.build(:dynamic_column => dynamic_column, :value => value)
|
246
|
-
end
|
247
|
-
}
|
248
|
-
end
|
249
|
-
|
250
|
-
def #{configuration[:as]}
|
251
|
-
h = {}
|
252
|
-
self.field_scope_#{configuration[:as]}.each { |i|
|
253
|
-
h[i.key] = nil
|
254
|
-
}
|
255
|
-
|
256
|
-
self.activerecord_dynamic_column_data.each { |i|
|
257
|
-
h[i.dynamic_column.key] = i.value unless !i.dynamic_column || !h.has_key?(i.dynamic_column.key)
|
258
|
-
}
|
259
|
-
|
260
|
-
h
|
261
|
-
end
|
262
|
-
|
263
|
-
def #{configuration[:as].to_s.singularize}_keys
|
264
|
-
self.field_scope_#{configuration[:as]}.collect { |i| i.key }
|
265
|
-
end
|
266
|
-
|
267
|
-
def field_scope_#{configuration[:as]}
|
268
|
-
# has_many relationship
|
269
|
-
if self.get_#{configuration[:as]}_field_scope.respond_to?(:select) && self.get_#{configuration[:as]}_field_scope.respond_to?(:collect)
|
270
|
-
self.get_#{configuration[:as]}_field_scope.collect { |i|
|
271
|
-
i.send("activerecord_dynamic_columns")
|
272
|
-
}.flatten.select { |i|
|
273
|
-
i.dynamic_type.to_s.empty? || i.dynamic_type.to_s == self.class.to_s
|
274
|
-
}
|
275
|
-
# belongs_to relationship
|
276
|
-
else
|
277
|
-
self.get_#{configuration[:as]}_field_scope.send("activerecord_dynamic_columns").select { |i|
|
278
|
-
# Only get things with no dynamic type defined or dynamic types defined as this class
|
279
|
-
i.dynamic_type.to_s.empty? || i.dynamic_type.to_s == self.class.to_s
|
280
|
-
}
|
281
|
-
end
|
282
|
-
end
|
283
|
-
|
284
|
-
protected
|
285
|
-
def get_#{configuration[:as]}_field_scope
|
286
|
-
#{configuration[:field_scope]}
|
287
|
-
end
|
288
|
-
|
289
|
-
# Whether this is storable
|
290
|
-
def storable_#{configuration[:as].to_s.singularize}_key?(key)
|
291
|
-
self.#{configuration[:as].to_s.singularize}_keys.include?(key.to_s)
|
292
|
-
end
|
293
|
-
|
294
|
-
# Figures out which dynamic_column has which key
|
295
|
-
def #{configuration[:as].to_s.singularize}_key_to_dynamic_column(key)
|
296
|
-
found = nil
|
297
|
-
if record = self.send('field_scope_#{configuration[:as]}').select { |i| i.key == key.to_s }.first
|
298
|
-
found = record
|
299
|
-
end
|
300
|
-
found
|
301
|
-
end
|
302
|
-
EOV
|
303
|
-
end
|
304
|
-
end
|
305
|
-
|
306
|
-
module InstanceMethods
|
307
|
-
end
|
308
|
-
end
|
309
16
|
end
|
310
17
|
|
311
18
|
if defined?(Rails::Railtie)
|
@@ -313,9 +20,13 @@ if defined?(Rails::Railtie)
|
|
313
20
|
initializer 'has_dynamic_columns.insert_into_active_record' do
|
314
21
|
ActiveSupport.on_load :active_record do
|
315
22
|
ActiveRecord::Base.send(:include, HasDynamicColumns::Model)
|
23
|
+
ActiveRecord::Relation.send(:include, HasDynamicColumns::ActiveRecord::Relation)
|
24
|
+
ActiveRecord::QueryMethods.send(:include, HasDynamicColumns::ActiveRecord::QueryMethods)
|
316
25
|
end
|
317
26
|
end
|
318
27
|
end
|
319
|
-
|
320
|
-
ActiveRecord::Base.send(:include, HasDynamicColumns::Model)
|
28
|
+
elsif defined?(ActiveRecord)
|
29
|
+
ActiveRecord::Base.send(:include, HasDynamicColumns::Model)
|
30
|
+
ActiveRecord::Relation.send(:include, HasDynamicColumns::ActiveRecord::Relation)
|
31
|
+
ActiveRecord::QueryMethods.send(:include, HasDynamicColumns::ActiveRecord::QueryMethods)
|
321
32
|
end
|