has_magic_columns 0.1.2 → 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.
- data/.rspec +1 -0
- data/README.md +35 -30
- data/Rakefile +16 -10
- data/has_magic_columns.gemspec +1 -1
- data/init.rb +5 -1
- data/lib/app/models/magic_attribute.rb +1 -1
- data/lib/has_magic_columns.rb +8 -4
- data/lib/has_magic_columns/active_record.rb +183 -0
- data/lib/has_magic_columns/railtie.rb +1 -12
- data/lib/has_magic_columns/version.rb +1 -1
- data/spec/database.yml +23 -0
- data/spec/finders/activerecord_test_connector.rb +113 -0
- data/spec/fixtures/account.rb +7 -0
- data/spec/fixtures/accounts.yml +2 -0
- data/spec/fixtures/people.yml +5 -0
- data/spec/fixtures/person.rb +5 -0
- data/spec/fixtures/schema.rb +61 -0
- data/spec/fixtures/user.rb +7 -0
- data/spec/fixtures/users.yml +7 -0
- data/spec/has_magic_columns_spec.rb +112 -0
- data/spec/spec_helper.rb +14 -0
- metadata +39 -17
- data/lib/has_magic_columns/has_magic_columns.rb +0 -172
- data/test/has_magic_columns_test.rb +0 -8
data/.rspec
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
--color --format documentation
|
data/README.md
CHANGED
@@ -30,37 +30,37 @@ Usage
|
|
30
30
|
|
31
31
|
Sprinkle a little magic into an existing model:
|
32
32
|
|
33
|
-
class
|
33
|
+
class Person < ActiveRecord::Base
|
34
34
|
has_magic_columns
|
35
35
|
end
|
36
36
|
|
37
37
|
Add magic columns to your model:
|
38
38
|
|
39
|
-
@
|
40
|
-
@
|
39
|
+
@charlie = Person.create(:email => "charlie@example.com")
|
40
|
+
@charlie.magic_columns.create(:name => "first_name")
|
41
41
|
|
42
42
|
Supply additional options if you have more specific requirements for your columns:
|
43
43
|
|
44
|
-
@
|
45
|
-
@
|
46
|
-
@
|
44
|
+
@charlie.magic_columns.create(:name => "last_name", :is_required => true)
|
45
|
+
@charlie.magic_columns.create(:name => "birthday", :datatype => :date)
|
46
|
+
@charlie.magic_columns.create(:name => "salary", :default => "40000", :pretty_name => "Yearly Salary")
|
47
47
|
|
48
48
|
The :datatype option supports :check_box_boolean, :date, :datetime, or :integer.
|
49
49
|
|
50
50
|
Use your new columns just like you would with any other ActiveRecord attribute:
|
51
51
|
|
52
|
-
@
|
53
|
-
@
|
54
|
-
@
|
55
|
-
@
|
52
|
+
@charlie.first_name = "Charlie"
|
53
|
+
@charlie.last_name = "Magic!"
|
54
|
+
@charlie.birthday = Date.today
|
55
|
+
@charlie.save
|
56
56
|
|
57
|
-
Find @
|
57
|
+
Find @charlie and inspect him:
|
58
58
|
|
59
|
-
@
|
60
|
-
@
|
61
|
-
@
|
62
|
-
@
|
63
|
-
@
|
59
|
+
@charlie = User.find(@charlie.id)
|
60
|
+
@charlie.first_name #=> "Charlie"
|
61
|
+
@charlie.last_name #=> "Magic!"
|
62
|
+
@charlie.birthday #=> #<Date: 4908497/2,0,2299161>
|
63
|
+
@charlie.salary #=> "40000", this is from :salary having a :default
|
64
64
|
|
65
65
|
## Inherited Model
|
66
66
|
|
@@ -71,6 +71,7 @@ as having magic columns:
|
|
71
71
|
has_many :users
|
72
72
|
has_magic_columns
|
73
73
|
end
|
74
|
+
@account = Account.create(:name => "BobCorp")
|
74
75
|
|
75
76
|
And declare the child as having magic columns :through the parent.
|
76
77
|
|
@@ -78,36 +79,34 @@ And declare the child as having magic columns :through the parent.
|
|
78
79
|
belongs_to :account
|
79
80
|
has_magic_columns :through => :account
|
80
81
|
end
|
82
|
+
@alice = User.create(:name => "alice", :account => @account)
|
81
83
|
|
82
84
|
To see all the magic columns available for a child from its parent:
|
83
85
|
|
84
|
-
@
|
85
|
-
@
|
86
|
+
@alice.magic_columns #=> [#<MagicColumn>,...]
|
87
|
+
@account.magic_columns #=> [#<MagicColumn>,...]
|
88
|
+
@alice.account.magic_columns #=> [#<MagicColumn>,...]
|
86
89
|
|
87
90
|
To add magic columns, go through the parent or child:
|
88
91
|
|
89
|
-
@
|
90
|
-
@
|
92
|
+
@alice.magic_columns.create(...)
|
93
|
+
@account.magic_columns.create(...)
|
91
94
|
|
92
95
|
All children for a given parent will have access to the same magic columns:
|
93
96
|
|
94
|
-
@
|
97
|
+
@alice.magic_columns.create(:name => "salary")
|
98
|
+
@alice.salary = "40000"
|
95
99
|
|
96
100
|
@bob = User.create(:name => "bob", :account => @account)
|
97
|
-
|
98
|
-
@bob.salary = "
|
99
|
-
|
100
|
-
@steve = User.create(:name => "bob", :account => @account)
|
101
|
-
# no need to add the column again
|
102
|
-
@steve.salary = "50000"
|
101
|
+
# Magic! No need to add the column again!
|
102
|
+
@bob.salary = "50000"
|
103
103
|
|
104
104
|
To Do
|
105
105
|
=====
|
106
106
|
|
107
|
-
|
108
|
-
done to polish it up:
|
107
|
+
Here's a short list of things that need to be done to polish up this gem:
|
109
108
|
|
110
|
-
* Test
|
109
|
+
* Test other parts of the data model (e.g. magic_attributes, magic_options)
|
111
110
|
* Benchmark and optimize
|
112
111
|
|
113
112
|
Maintainers
|
@@ -119,3 +118,9 @@ Maintainers
|
|
119
118
|
Contribute
|
120
119
|
==========
|
121
120
|
See the [CONTRIBUTORS guide](https://github.com/latortuga/has_magic_columns/blob/master/CONTRIBUTORS.md).
|
121
|
+
|
122
|
+
Credits
|
123
|
+
=======
|
124
|
+
|
125
|
+
* Thank you to Brandon Keene for his original work making this plugin.
|
126
|
+
* Thank you to the [will_paginate](https://github.com/mislav/will_paginate) gem for iinspiration and code examples for how to test a Rails plugin.
|
data/Rakefile
CHANGED
@@ -1,20 +1,11 @@
|
|
1
1
|
require 'rake'
|
2
2
|
gem 'rdoc'
|
3
3
|
require 'rdoc/task'
|
4
|
-
require '
|
4
|
+
require 'rspec/core/rake_task'
|
5
5
|
|
6
6
|
require 'bundler'
|
7
7
|
Bundler::GemHelper.install_tasks
|
8
8
|
|
9
|
-
#desc 'Default: run unit tests.'
|
10
|
-
task :default => :test
|
11
|
-
|
12
|
-
Rake::TestTask.new do |t|
|
13
|
-
t.libs << 'lib'
|
14
|
-
t.pattern = 'test/**/*_test.rb'
|
15
|
-
t.verbose = true
|
16
|
-
end
|
17
|
-
|
18
9
|
desc 'Generate documentation.'
|
19
10
|
RDoc::Task.new do |rdoc|
|
20
11
|
rdoc.main = "README.md"
|
@@ -23,3 +14,18 @@ RDoc::Task.new do |rdoc|
|
|
23
14
|
rdoc.title = 'HasMagicColumns'
|
24
15
|
rdoc.options << '--line-numbers' << '--inline-source'
|
25
16
|
end
|
17
|
+
|
18
|
+
task :default => :spec
|
19
|
+
|
20
|
+
desc 'Run specs'
|
21
|
+
RSpec::Core::RakeTask.new(:spec) do |t|
|
22
|
+
t.pattern = 'spec/**/*_spec.rb'
|
23
|
+
t.ruby_opts = "-Ilib:spec"
|
24
|
+
end
|
25
|
+
|
26
|
+
namespace :spec do
|
27
|
+
desc "Run Rails specs"
|
28
|
+
RSpec::Core::RakeTask.new(:rails) do |t|
|
29
|
+
t.pattern = %w'spec/finders/active_record_spec.rb spec/view_helpers/action_view_spec.rb'
|
30
|
+
end
|
31
|
+
end
|
data/has_magic_columns.gemspec
CHANGED
@@ -14,7 +14,7 @@ Gem::Specification.new do |s|
|
|
14
14
|
s.date = Date.today
|
15
15
|
|
16
16
|
s.files = `git ls-files`.split("\n")
|
17
|
-
s.test_files = `git ls-files --
|
17
|
+
s.test_files = `git ls-files -- spec/`.split("\n")
|
18
18
|
s.require_paths = ["lib"]
|
19
19
|
|
20
20
|
s.add_dependency("activesupport", ["~> 3.0"])
|
data/init.rb
CHANGED
@@ -24,6 +24,6 @@ private
|
|
24
24
|
|
25
25
|
def find_magic_option_for(value)
|
26
26
|
magic_column.magic_options.find(:first,
|
27
|
-
:conditions => ["value = ? or synonym = ?", value, value])
|
27
|
+
:conditions => ["value = ? or synonym = ?", value, value]) unless magic_column.nil? or magic_column.magic_options.nil?
|
28
28
|
end
|
29
29
|
end
|
data/lib/has_magic_columns.rb
CHANGED
@@ -1,7 +1,3 @@
|
|
1
|
-
require 'has_magic_columns/has_magic_columns'
|
2
|
-
require 'has_magic_columns/version'
|
3
|
-
require 'has_magic_columns/railtie' if defined?(Rails)
|
4
|
-
|
5
1
|
# Has Magic Columns
|
6
2
|
#
|
7
3
|
# Copyright (c) 2007 Brandon Keene <bkeene AT gmail DOT com>
|
@@ -22,3 +18,11 @@ require 'has_magic_columns/railtie' if defined?(Rails)
|
|
22
18
|
module HasMagicColumns # :nodoc:
|
23
19
|
end
|
24
20
|
|
21
|
+
require 'has_magic_columns/version'
|
22
|
+
|
23
|
+
if defined? Rails::Railtie
|
24
|
+
require 'has_magic_columns/railtie'
|
25
|
+
elsif defined? Rails::Initializer
|
26
|
+
$stderr.puts "\nhas_magic_columns is not compatible with Rails 2, use at your own risk.\n\n"
|
27
|
+
end
|
28
|
+
|
@@ -0,0 +1,183 @@
|
|
1
|
+
require 'active_support'
|
2
|
+
require 'active_record'
|
3
|
+
|
4
|
+
module HasMagicColumns #:nodoc:
|
5
|
+
module ActiveRecord
|
6
|
+
module ClassMethods
|
7
|
+
def has_magic_columns(options = {})
|
8
|
+
unless magical?
|
9
|
+
# Associations
|
10
|
+
has_many :magic_attribute_relationships, :as => :owner, :dependent => :destroy
|
11
|
+
has_many :magic_attributes, :through => :magic_attribute_relationships, :dependent => :destroy
|
12
|
+
|
13
|
+
# Eager loading - EXPERIMENTAL!
|
14
|
+
if options[:eager]
|
15
|
+
class_eval do
|
16
|
+
def after_initialize
|
17
|
+
initialize_magic_columns
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
# Inheritence
|
23
|
+
cattr_accessor :inherited_from
|
24
|
+
|
25
|
+
# if options[:through] is supplied, treat as an inherited relationship
|
26
|
+
if self.inherited_from = options[:through]
|
27
|
+
class_eval do
|
28
|
+
def inherited_magic_columns
|
29
|
+
raise "Cannot inherit MagicColumns from a non-existant association: #{@inherited_from}" unless self.class.method_defined?(inherited_from)# and self.send(inherited_from)
|
30
|
+
self.send(inherited_from).magic_columns
|
31
|
+
end
|
32
|
+
end
|
33
|
+
alias_method :magic_columns, :inherited_magic_columns unless method_defined? :magic_columns
|
34
|
+
|
35
|
+
# otherwise the calling model has the relationships
|
36
|
+
else
|
37
|
+
has_many :magic_column_relationships, :as => :owner, :dependent => :destroy
|
38
|
+
has_many :magic_columns, :through => :magic_column_relationships, :dependent => :destroy
|
39
|
+
end
|
40
|
+
|
41
|
+
# Hook into Base
|
42
|
+
class_eval do
|
43
|
+
alias_method :reload_without_magic, :reload
|
44
|
+
alias_method :create_or_update_without_magic, :create_or_update
|
45
|
+
alias_method :read_attribute_without_magic, :read_attribute
|
46
|
+
end
|
47
|
+
end
|
48
|
+
include InstanceMethods
|
49
|
+
|
50
|
+
# Add Magic to Base
|
51
|
+
alias_method :reload, :reload_with_magic
|
52
|
+
alias_method :read_attribute, :read_attribute_with_magic
|
53
|
+
alias_method :create_or_update, :create_or_update_with_magic
|
54
|
+
end
|
55
|
+
|
56
|
+
def magical?
|
57
|
+
self.included_modules.include?(InstanceMethods)
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
module InstanceMethods #:nodoc:
|
62
|
+
# Reinitialize MagicColumns and MagicAttributes when Model is reloaded
|
63
|
+
def reload_with_magic
|
64
|
+
initialize_magic_columns
|
65
|
+
reload_without_magic
|
66
|
+
end
|
67
|
+
|
68
|
+
def update_attributes(new_attributes)
|
69
|
+
attributes = new_attributes.stringify_keys
|
70
|
+
magic_attrs = magic_columns.map(&:name)
|
71
|
+
|
72
|
+
super(attributes.select{ |k, v| !magic_attrs.include?(k) })
|
73
|
+
attributes.select{ |k, v| magic_attrs.include?(k) }.each do |k, v|
|
74
|
+
col = find_magic_column_by_name(k)
|
75
|
+
attr = find_magic_attribute_by_column(col).first
|
76
|
+
attr.update_attributes(:value => v)
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
private
|
81
|
+
|
82
|
+
# Save MagicAttributes from @attributes
|
83
|
+
def create_or_update_with_magic
|
84
|
+
if result = create_or_update_without_magic
|
85
|
+
magic_columns.each do |column|
|
86
|
+
value = @attributes[column.name]
|
87
|
+
existing = find_magic_attribute_by_column(column)
|
88
|
+
|
89
|
+
unless column.datatype == 'check_box_multiple'
|
90
|
+
(attr = existing.first) ?
|
91
|
+
update_magic_attribute(attr, value) :
|
92
|
+
create_magic_attribute(column, value)
|
93
|
+
else
|
94
|
+
#TODO - make this more efficient
|
95
|
+
value = [value] unless value.is_a? Array
|
96
|
+
existing.map(&:destroy) if existing
|
97
|
+
value.collect {|v| create_magic_attribute(column, v)}
|
98
|
+
end
|
99
|
+
end
|
100
|
+
end
|
101
|
+
result
|
102
|
+
end
|
103
|
+
|
104
|
+
# Load (lazily) MagicAttributes or fall back
|
105
|
+
def method_missing(method_id, *args)
|
106
|
+
super(method_id, *args)
|
107
|
+
rescue NoMethodError
|
108
|
+
method_name = method_id.to_s
|
109
|
+
attr_names = magic_columns.map(&:name)
|
110
|
+
initialize_magic_columns and retry if attr_names.include?(method_name) or
|
111
|
+
(md = /[\?|\=]/.match(method_name) and
|
112
|
+
attr_names.include?(md.pre_match))
|
113
|
+
super(method_id, *args)
|
114
|
+
end
|
115
|
+
|
116
|
+
# Load the MagicAttribute(s) associated with attr_name and cast them to proper type.
|
117
|
+
def read_attribute_with_magic(attr_name)
|
118
|
+
return read_attribute_without_magic(attr_name) if column_for_attribute(attr_name) # filter for regular columns
|
119
|
+
attr_name = attr_name.to_s
|
120
|
+
|
121
|
+
if !(value = @attributes[attr_name]).nil?
|
122
|
+
if column = find_magic_column_by_name(attr_name)
|
123
|
+
if value.is_a? Array
|
124
|
+
value.map {|v| column.type_cast(v)}
|
125
|
+
else
|
126
|
+
column.type_cast(value)
|
127
|
+
end
|
128
|
+
else
|
129
|
+
value
|
130
|
+
end
|
131
|
+
else
|
132
|
+
nil
|
133
|
+
end
|
134
|
+
end
|
135
|
+
|
136
|
+
# Lookup all MagicAttributes and setup @attributes
|
137
|
+
def initialize_magic_columns
|
138
|
+
magic_columns.each do |column|
|
139
|
+
attribute = find_magic_attribute_by_column(column)
|
140
|
+
name = column.name
|
141
|
+
|
142
|
+
# Validation
|
143
|
+
self.class.validates_presence_of(name) if column.is_required?
|
144
|
+
|
145
|
+
# Write attribute
|
146
|
+
unless column.datatype == 'check_box_multiple'
|
147
|
+
(attr = attribute.first) ?
|
148
|
+
write_attribute(name, attr.to_s) :
|
149
|
+
write_attribute(name, column.default)
|
150
|
+
else
|
151
|
+
write_attribute(name, attribute.map(&:to_s))
|
152
|
+
end
|
153
|
+
end
|
154
|
+
end
|
155
|
+
|
156
|
+
def find_magic_attribute_by_column(column)
|
157
|
+
magic_attributes.to_a.find_all {|attr| attr.magic_column_id == column.id}
|
158
|
+
end
|
159
|
+
|
160
|
+
def find_magic_column_by_name(attr_name)
|
161
|
+
magic_columns.to_a.find {|column| column.name == attr_name}
|
162
|
+
end
|
163
|
+
|
164
|
+
def create_magic_attribute(magic_column, value)
|
165
|
+
magic_attributes << MagicAttribute.create(:magic_column => magic_column, :value => value)
|
166
|
+
end
|
167
|
+
|
168
|
+
def update_magic_attribute(magic_attribute, value)
|
169
|
+
magic_attribute.update_attributes(:value => value)
|
170
|
+
end
|
171
|
+
end
|
172
|
+
|
173
|
+
# mix into Active Record
|
174
|
+
::ActiveRecord::Base.extend ClassMethods
|
175
|
+
|
176
|
+
%w{ models }.each do |dir|
|
177
|
+
path = File.join(File.dirname(__FILE__), '../app', dir)
|
178
|
+
$LOAD_PATH << path
|
179
|
+
ActiveSupport::Dependencies.autoload_paths << path
|
180
|
+
ActiveSupport::Dependencies.autoload_once_paths.delete(path)
|
181
|
+
end
|
182
|
+
end
|
183
|
+
end
|
@@ -3,19 +3,8 @@ require 'has_magic_columns'
|
|
3
3
|
module HasMagicColumns
|
4
4
|
class Railtie < Rails::Railtie
|
5
5
|
initializer "has_magic_columns" do
|
6
|
-
|
7
|
-
# I think this is probably a ghetto way of doing this
|
8
|
-
# based on some limited research into other plugins. Neverhtless
|
9
|
-
# it's the only way I know for the moment.
|
10
6
|
ActiveSupport.on_load :active_record do
|
11
|
-
|
12
|
-
|
13
|
-
%w{ models }.each do |dir|
|
14
|
-
path = File.join(File.dirname(__FILE__), '../app', dir)
|
15
|
-
$LOAD_PATH << path
|
16
|
-
ActiveSupport::Dependencies.autoload_paths << path
|
17
|
-
ActiveSupport::Dependencies.autoload_once_paths.delete(path)
|
18
|
-
end
|
7
|
+
require 'has_magic_columns/active_record'
|
19
8
|
end
|
20
9
|
end
|
21
10
|
end
|
data/spec/database.yml
ADDED
@@ -0,0 +1,23 @@
|
|
1
|
+
sqlite3:
|
2
|
+
database: ":memory:"
|
3
|
+
adapter: sqlite3
|
4
|
+
timeout: 500
|
5
|
+
|
6
|
+
mysql:
|
7
|
+
adapter: mysql
|
8
|
+
database: has_magic_columns
|
9
|
+
username:
|
10
|
+
encoding: utf8
|
11
|
+
|
12
|
+
mysql2:
|
13
|
+
adapter: mysql2
|
14
|
+
database: has_magic_columns
|
15
|
+
username:
|
16
|
+
encoding: utf8
|
17
|
+
|
18
|
+
postgres:
|
19
|
+
adapter: postgresql
|
20
|
+
database: has_magic_columns
|
21
|
+
username: postgres
|
22
|
+
min_messages: warning
|
23
|
+
|
@@ -0,0 +1,113 @@
|
|
1
|
+
require 'active_record'
|
2
|
+
require 'active_record/fixtures'
|
3
|
+
require 'active_support/multibyte' # needed for Ruby 1.9.1
|
4
|
+
|
5
|
+
$query_count = 0
|
6
|
+
$query_sql = []
|
7
|
+
|
8
|
+
ignore_sql = /
|
9
|
+
^(
|
10
|
+
PRAGMA | SHOW\ max_identifier_length |
|
11
|
+
SELECT\ (currval|CAST|@@IDENTITY|@@ROWCOUNT) |
|
12
|
+
SHOW\ (FIELDS|TABLES)
|
13
|
+
)\b |
|
14
|
+
\bFROM\ (sqlite_master|pg_tables|pg_attribute)\b
|
15
|
+
/x
|
16
|
+
|
17
|
+
ActiveSupport::Notifications.subscribe(/^sql\./) do |*args|
|
18
|
+
payload = args.last
|
19
|
+
unless payload[:name] =~ /^Fixture/ or payload[:sql] =~ ignore_sql
|
20
|
+
$query_count += 1
|
21
|
+
$query_sql << payload[:sql]
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
module ActiverecordTestConnector
|
26
|
+
extend self
|
27
|
+
|
28
|
+
attr_accessor :able_to_connect
|
29
|
+
attr_accessor :connected
|
30
|
+
|
31
|
+
FIXTURES_PATH = File.expand_path('../../fixtures', __FILE__)
|
32
|
+
|
33
|
+
Fixtures = defined?(ActiveRecord::Fixtures) ? ActiveRecord::Fixtures : ::Fixtures
|
34
|
+
|
35
|
+
# Set our defaults
|
36
|
+
self.connected = false
|
37
|
+
self.able_to_connect = true
|
38
|
+
|
39
|
+
def setup
|
40
|
+
unless self.connected || !self.able_to_connect
|
41
|
+
setup_connection
|
42
|
+
load_schema
|
43
|
+
add_load_path FIXTURES_PATH
|
44
|
+
self.connected = true
|
45
|
+
end
|
46
|
+
rescue Exception => e # errors from ActiveRecord setup
|
47
|
+
$stderr.puts "\nSkipping ActiveRecord tests: #{e}\n\n"
|
48
|
+
self.able_to_connect = false
|
49
|
+
end
|
50
|
+
|
51
|
+
private
|
52
|
+
|
53
|
+
def add_load_path(path)
|
54
|
+
dep = defined?(ActiveSupport::Dependencies) ? ActiveSupport::Dependencies : ::Dependencies
|
55
|
+
dep.autoload_paths.unshift path
|
56
|
+
end
|
57
|
+
|
58
|
+
def setup_connection
|
59
|
+
db = ENV['DB'].blank? ? 'sqlite3' : ENV['DB']
|
60
|
+
|
61
|
+
configurations = YAML.load_file(File.expand_path('../../database.yml', __FILE__))
|
62
|
+
raise "no configuration for '#{db}'" unless configurations.key? db
|
63
|
+
configuration = configurations[db]
|
64
|
+
|
65
|
+
# ActiveRecord::Base.logger = Logger.new(STDOUT) if $0 == 'irb'
|
66
|
+
puts "using #{configuration['adapter']} adapter"
|
67
|
+
|
68
|
+
ActiveRecord::Base.configurations = { db => configuration }
|
69
|
+
ActiveRecord::Base.establish_connection(db)
|
70
|
+
ActiveRecord::Base.default_timezone = :utc
|
71
|
+
end
|
72
|
+
|
73
|
+
def load_schema
|
74
|
+
ActiveRecord::Base.silence do
|
75
|
+
ActiveRecord::Migration.verbose = false
|
76
|
+
load File.join(FIXTURES_PATH, 'schema.rb')
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
module FixtureSetup
|
81
|
+
def fixtures(*tables)
|
82
|
+
table_names = tables.map { |t| t.to_s }
|
83
|
+
|
84
|
+
fixtures = Fixtures.create_fixtures ActiverecordTestConnector::FIXTURES_PATH, table_names
|
85
|
+
@@loaded_fixtures = {}
|
86
|
+
@@fixture_cache = {}
|
87
|
+
|
88
|
+
unless fixtures.nil?
|
89
|
+
if fixtures.instance_of?(Fixtures)
|
90
|
+
@@loaded_fixtures[fixtures.table_name] = fixtures
|
91
|
+
else
|
92
|
+
fixtures.each { |f| @@loaded_fixtures[f.table_name] = f }
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
96
|
+
table_names.each do |table_name|
|
97
|
+
define_method(table_name) do |*fixtures|
|
98
|
+
@@fixture_cache[table_name] ||= {}
|
99
|
+
|
100
|
+
instances = fixtures.map do |fixture|
|
101
|
+
if @@loaded_fixtures[table_name][fixture.to_s]
|
102
|
+
@@fixture_cache[table_name][fixture] ||= @@loaded_fixtures[table_name][fixture.to_s].find
|
103
|
+
else
|
104
|
+
raise StandardError, "No fixture with name '#{fixture}' found for table '#{table_name}'"
|
105
|
+
end
|
106
|
+
end
|
107
|
+
|
108
|
+
instances.size == 1 ? instances.first : instances
|
109
|
+
end
|
110
|
+
end
|
111
|
+
end
|
112
|
+
end
|
113
|
+
end
|
@@ -0,0 +1,7 @@
|
|
1
|
+
# Account class tests the case where has_magic_columns is used in a parent-
|
2
|
+
# child fashion where the Account model has the magic columns and the User
|
3
|
+
# model inherits them through the associated Account.
|
4
|
+
class Account < ActiveRecord::Base
|
5
|
+
has_many :users
|
6
|
+
has_magic_columns
|
7
|
+
end
|
@@ -0,0 +1,61 @@
|
|
1
|
+
ActiveRecord::Schema.define do
|
2
|
+
|
3
|
+
create_table "users", :force => true do |t|
|
4
|
+
t.column "name", :text
|
5
|
+
t.column "account_id", :integer
|
6
|
+
end
|
7
|
+
|
8
|
+
create_table "accounts", :force => true do |t|
|
9
|
+
t.column "name", :text
|
10
|
+
end
|
11
|
+
|
12
|
+
create_table "people", :force => true do |t|
|
13
|
+
t.column "name", :text
|
14
|
+
end
|
15
|
+
|
16
|
+
|
17
|
+
# Has Magic Columns migration generator output
|
18
|
+
|
19
|
+
create_table :magic_columns do |t|
|
20
|
+
t.column :name, :string
|
21
|
+
t.column :pretty_name, :string
|
22
|
+
t.column :datatype, :string, :default => "string"
|
23
|
+
t.column :default, :string
|
24
|
+
t.column :is_required, :boolean, :default => false
|
25
|
+
t.column :include_blank, :boolean, :default => false
|
26
|
+
t.column :allow_other, :boolean, :default => true
|
27
|
+
t.column :created_at, :datetime
|
28
|
+
t.column :updated_at, :datetime
|
29
|
+
end
|
30
|
+
|
31
|
+
create_table :magic_attributes do |t|
|
32
|
+
t.column :magic_column_id, :integer
|
33
|
+
t.column :magic_option_id, :integer
|
34
|
+
t.column :value, :string
|
35
|
+
t.column :created_at, :datetime
|
36
|
+
t.column :updated_at, :datetime
|
37
|
+
end
|
38
|
+
|
39
|
+
create_table :magic_options do |t|
|
40
|
+
t.column :magic_column_id, :integer
|
41
|
+
t.column :value, :string
|
42
|
+
t.column :synonym, :string
|
43
|
+
t.column :created_at, :datetime
|
44
|
+
t.column :updated_at, :datetime
|
45
|
+
end
|
46
|
+
|
47
|
+
create_table :magic_column_relationships do |t|
|
48
|
+
t.column :magic_column_id, :integer
|
49
|
+
t.column :owner_id, :integer
|
50
|
+
t.column :owner_type, :string
|
51
|
+
t.column :created_at, :datetime
|
52
|
+
t.column :updated_at, :datetime
|
53
|
+
end
|
54
|
+
|
55
|
+
create_table :magic_attribute_relationships do |t|
|
56
|
+
t.column :magic_attribute_id, :integer
|
57
|
+
t.column :owner_id, :integer
|
58
|
+
t.column :owner_type, :string
|
59
|
+
end
|
60
|
+
|
61
|
+
end
|
@@ -0,0 +1,7 @@
|
|
1
|
+
# User class tests the case where has_magic_columns is used in a parent-
|
2
|
+
# child fashion where the Account model has the magic columns and the User
|
3
|
+
# model inherits them through the associated Account.
|
4
|
+
class User < ActiveRecord::Base
|
5
|
+
belongs_to :account
|
6
|
+
has_magic_columns :through => :account
|
7
|
+
end
|
@@ -0,0 +1,112 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'has_magic_columns/active_record'
|
3
|
+
require 'finders/activerecord_test_connector'
|
4
|
+
|
5
|
+
ActiverecordTestConnector.setup
|
6
|
+
abort unless ActiverecordTestConnector.able_to_connect
|
7
|
+
|
8
|
+
describe HasMagicColumns do
|
9
|
+
extend ActiverecordTestConnector::FixtureSetup
|
10
|
+
|
11
|
+
fixtures :people, :accounts, :users
|
12
|
+
|
13
|
+
context "on a single model" do
|
14
|
+
before(:each) do
|
15
|
+
@charlie = people(:charlie)
|
16
|
+
end
|
17
|
+
|
18
|
+
it "initializes magic columns correctly" do
|
19
|
+
@charlie.should_not be_nil
|
20
|
+
@charlie.class.should be(Person)
|
21
|
+
@charlie.magic_columns.should_not be_nil
|
22
|
+
end
|
23
|
+
|
24
|
+
it "allows adding a magic column" do
|
25
|
+
@charlie.magic_columns.create(:name => 'salary')
|
26
|
+
@charlie.magic_columns.length.should be(1)
|
27
|
+
end
|
28
|
+
|
29
|
+
it "allows setting and saving of magic attributes" do
|
30
|
+
@charlie.magic_columns.create(:name => 'salary')
|
31
|
+
@charlie.salary = 50000
|
32
|
+
@charlie.save
|
33
|
+
@charlie = Person.find(people(:charlie).id)
|
34
|
+
@charlie.salary.should_not be_nil
|
35
|
+
end
|
36
|
+
|
37
|
+
#it "forces required if is_required is true" do
|
38
|
+
# # TODO figure out why this fails
|
39
|
+
# @charlie.magic_columns.create(:name => "last_name", :is_required => true)
|
40
|
+
# @charlie.save.should be_false
|
41
|
+
#end
|
42
|
+
|
43
|
+
it "allows datatype to be :date" do
|
44
|
+
@charlie.magic_columns.create(:name => "birthday", :datatype => :date)
|
45
|
+
@charlie.birthday = Date.today
|
46
|
+
@charlie.save.should be_true
|
47
|
+
end
|
48
|
+
|
49
|
+
it "allows datatype to be :datetime" do
|
50
|
+
@charlie.magic_columns.create(:name => "signed_up_at", :datatype => :datetime)
|
51
|
+
@charlie.signed_up_at = DateTime.now
|
52
|
+
@charlie.save.should be_true
|
53
|
+
end
|
54
|
+
|
55
|
+
it "allows datatype to be :integer" do
|
56
|
+
@charlie.magic_columns.create(:name => "age", :datatype => :integer)
|
57
|
+
@charlie.age = 5
|
58
|
+
@charlie.save.should be_true
|
59
|
+
end
|
60
|
+
|
61
|
+
it "allows datatype to be :check_box_boolean" do
|
62
|
+
@charlie.magic_columns.create(:name => "retired", :datatype => :check_box_boolean)
|
63
|
+
@charlie.retired = false
|
64
|
+
@charlie.save.should be_true
|
65
|
+
end
|
66
|
+
|
67
|
+
it "allows default to be set" do
|
68
|
+
@charlie.magic_columns.create(:name => "bonus", :default => "40000")
|
69
|
+
@charlie.bonus.should == "40000"
|
70
|
+
end
|
71
|
+
|
72
|
+
it "allows a pretty display name to be set" do
|
73
|
+
@charlie.magic_columns.create(:name => "zip", :pretty_name => "Zip Code")
|
74
|
+
@charlie.magic_columns.last.pretty_name.should == "Zip Code"
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
context "in a parent-child relationship" do
|
79
|
+
before(:each) do
|
80
|
+
@alice = users(:alice)
|
81
|
+
@account = accounts(:important)
|
82
|
+
end
|
83
|
+
|
84
|
+
it "initializes magic columns correctly" do
|
85
|
+
@alice.should_not be_nil
|
86
|
+
@alice.class.should be(User)
|
87
|
+
@alice.magic_columns.should_not be_nil
|
88
|
+
|
89
|
+
@account.should_not be_nil
|
90
|
+
@account.class.should be(Account)
|
91
|
+
@alice.magic_columns.should_not be_nil
|
92
|
+
end
|
93
|
+
|
94
|
+
it "allows adding a magic column to the child" do
|
95
|
+
@alice.magic_columns.create(:name => 'salary')
|
96
|
+
lambda{@alice.salary}.should_not raise_error
|
97
|
+
lambda{@account.reload_with_magic.salary}.should_not raise_error
|
98
|
+
end
|
99
|
+
|
100
|
+
it "allows adding a magic column to the parent" do
|
101
|
+
@account.magic_columns.create(:name => 'age')
|
102
|
+
lambda{@alice.reload_with_magic.age}.should_not raise_error
|
103
|
+
end
|
104
|
+
|
105
|
+
it "sets magic columns for all child models" do
|
106
|
+
@bob = users(:bob)
|
107
|
+
@bob.magic_columns.create(:name => 'birthday')
|
108
|
+
@alice.reload_with_magic
|
109
|
+
lambda{@alice.birthday}.should_not raise_error
|
110
|
+
end
|
111
|
+
end
|
112
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
require 'rspec'
|
2
|
+
begin
|
3
|
+
require 'ruby-debug'
|
4
|
+
rescue LoadError
|
5
|
+
# no debugger available
|
6
|
+
end
|
7
|
+
|
8
|
+
RSpec.configure do |config|
|
9
|
+
# config.include My::Pony, My::Horse, :type => :farm
|
10
|
+
# config.include MyExtras
|
11
|
+
# config.predicate_matchers[:swim] = :can_swim?
|
12
|
+
# config.mock_with :mocha
|
13
|
+
end
|
14
|
+
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: has_magic_columns
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.0
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -11,11 +11,11 @@ authors:
|
|
11
11
|
autorequire:
|
12
12
|
bindir: bin
|
13
13
|
cert_chain: []
|
14
|
-
date: 2011-09-
|
14
|
+
date: 2011-09-08 00:00:00.000000000Z
|
15
15
|
dependencies:
|
16
16
|
- !ruby/object:Gem::Dependency
|
17
17
|
name: activesupport
|
18
|
-
requirement: &
|
18
|
+
requirement: &73612880 !ruby/object:Gem::Requirement
|
19
19
|
none: false
|
20
20
|
requirements:
|
21
21
|
- - ~>
|
@@ -23,10 +23,10 @@ dependencies:
|
|
23
23
|
version: '3.0'
|
24
24
|
type: :runtime
|
25
25
|
prerelease: false
|
26
|
-
version_requirements: *
|
26
|
+
version_requirements: *73612880
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
28
|
name: activerecord
|
29
|
-
requirement: &
|
29
|
+
requirement: &73612610 !ruby/object:Gem::Requirement
|
30
30
|
none: false
|
31
31
|
requirements:
|
32
32
|
- - ~>
|
@@ -34,10 +34,10 @@ dependencies:
|
|
34
34
|
version: '3.0'
|
35
35
|
type: :runtime
|
36
36
|
prerelease: false
|
37
|
-
version_requirements: *
|
37
|
+
version_requirements: *73612610
|
38
38
|
- !ruby/object:Gem::Dependency
|
39
39
|
name: rails
|
40
|
-
requirement: &
|
40
|
+
requirement: &73612370 !ruby/object:Gem::Requirement
|
41
41
|
none: false
|
42
42
|
requirements:
|
43
43
|
- - ~>
|
@@ -45,10 +45,10 @@ dependencies:
|
|
45
45
|
version: '3.0'
|
46
46
|
type: :development
|
47
47
|
prerelease: false
|
48
|
-
version_requirements: *
|
48
|
+
version_requirements: *73612370
|
49
49
|
- !ruby/object:Gem::Dependency
|
50
50
|
name: sqlite3
|
51
|
-
requirement: &
|
51
|
+
requirement: &73612180 !ruby/object:Gem::Requirement
|
52
52
|
none: false
|
53
53
|
requirements:
|
54
54
|
- - ! '>='
|
@@ -56,10 +56,10 @@ dependencies:
|
|
56
56
|
version: '0'
|
57
57
|
type: :development
|
58
58
|
prerelease: false
|
59
|
-
version_requirements: *
|
59
|
+
version_requirements: *73612180
|
60
60
|
- !ruby/object:Gem::Dependency
|
61
61
|
name: rspec
|
62
|
-
requirement: &
|
62
|
+
requirement: &73611900 !ruby/object:Gem::Requirement
|
63
63
|
none: false
|
64
64
|
requirements:
|
65
65
|
- - ~>
|
@@ -67,10 +67,10 @@ dependencies:
|
|
67
67
|
version: '2.0'
|
68
68
|
type: :development
|
69
69
|
prerelease: false
|
70
|
-
version_requirements: *
|
70
|
+
version_requirements: *73611900
|
71
71
|
- !ruby/object:Gem::Dependency
|
72
72
|
name: rdoc
|
73
|
-
requirement: &
|
73
|
+
requirement: &73611670 !ruby/object:Gem::Requirement
|
74
74
|
none: false
|
75
75
|
requirements:
|
76
76
|
- - ! '>='
|
@@ -78,7 +78,7 @@ dependencies:
|
|
78
78
|
version: '0'
|
79
79
|
type: :development
|
80
80
|
prerelease: false
|
81
|
-
version_requirements: *
|
81
|
+
version_requirements: *73611670
|
82
82
|
description: Allow addition of custom 'magic' columns to ActiveRecord models.
|
83
83
|
email:
|
84
84
|
- latortuga@gmail.com
|
@@ -88,6 +88,7 @@ extensions: []
|
|
88
88
|
extra_rdoc_files: []
|
89
89
|
files:
|
90
90
|
- .gitignore
|
91
|
+
- .rspec
|
91
92
|
- CONTRIBUTORS.md
|
92
93
|
- Gemfile
|
93
94
|
- LICENSE
|
@@ -104,10 +105,20 @@ files:
|
|
104
105
|
- lib/generators/has_magic_columns/install/install_generator.rb
|
105
106
|
- lib/generators/has_magic_columns/install/templates/migration.rb
|
106
107
|
- lib/has_magic_columns.rb
|
107
|
-
- lib/has_magic_columns/
|
108
|
+
- lib/has_magic_columns/active_record.rb
|
108
109
|
- lib/has_magic_columns/railtie.rb
|
109
110
|
- lib/has_magic_columns/version.rb
|
110
|
-
-
|
111
|
+
- spec/database.yml
|
112
|
+
- spec/finders/activerecord_test_connector.rb
|
113
|
+
- spec/fixtures/account.rb
|
114
|
+
- spec/fixtures/accounts.yml
|
115
|
+
- spec/fixtures/people.yml
|
116
|
+
- spec/fixtures/person.rb
|
117
|
+
- spec/fixtures/schema.rb
|
118
|
+
- spec/fixtures/user.rb
|
119
|
+
- spec/fixtures/users.yml
|
120
|
+
- spec/has_magic_columns_spec.rb
|
121
|
+
- spec/spec_helper.rb
|
111
122
|
homepage: https://github.com/latortuga/has_magic_columns
|
112
123
|
licenses: []
|
113
124
|
post_install_message:
|
@@ -132,4 +143,15 @@ rubygems_version: 1.8.0
|
|
132
143
|
signing_key:
|
133
144
|
specification_version: 3
|
134
145
|
summary: Custom fields for Rails 3
|
135
|
-
test_files:
|
146
|
+
test_files:
|
147
|
+
- spec/database.yml
|
148
|
+
- spec/finders/activerecord_test_connector.rb
|
149
|
+
- spec/fixtures/account.rb
|
150
|
+
- spec/fixtures/accounts.yml
|
151
|
+
- spec/fixtures/people.yml
|
152
|
+
- spec/fixtures/person.rb
|
153
|
+
- spec/fixtures/schema.rb
|
154
|
+
- spec/fixtures/user.rb
|
155
|
+
- spec/fixtures/users.yml
|
156
|
+
- spec/has_magic_columns_spec.rb
|
157
|
+
- spec/spec_helper.rb
|
@@ -1,172 +0,0 @@
|
|
1
|
-
module HasMagicColumns #:nodoc:
|
2
|
-
def self.included(base) # :nodoc:
|
3
|
-
base.extend ClassMethods
|
4
|
-
end
|
5
|
-
|
6
|
-
module ClassMethods
|
7
|
-
def has_magic_columns(options = {})
|
8
|
-
unless magical?
|
9
|
-
# Associations
|
10
|
-
has_many :magic_attribute_relationships, :as => :owner, :dependent => :destroy
|
11
|
-
has_many :magic_attributes, :through => :magic_attribute_relationships, :dependent => :destroy
|
12
|
-
|
13
|
-
# Eager loading - EXPERIMENTAL!
|
14
|
-
if options[:eager]
|
15
|
-
class_eval do
|
16
|
-
def after_initialize
|
17
|
-
initialize_magic_columns
|
18
|
-
end
|
19
|
-
end
|
20
|
-
end
|
21
|
-
|
22
|
-
# Inheritence
|
23
|
-
cattr_accessor :inherited_from
|
24
|
-
|
25
|
-
# if options[:through] is supplied, treat as an inherited relationship
|
26
|
-
if self.inherited_from = options[:through]
|
27
|
-
class_eval do
|
28
|
-
def inherited_magic_columns
|
29
|
-
raise "Cannot inherit MagicColumns from a non-existant association: #{@inherited_from}" unless self.class.method_defined?(inherited_from)# and self.send(inherited_from)
|
30
|
-
self.send(inherited_from).magic_columns
|
31
|
-
end
|
32
|
-
end
|
33
|
-
alias_method :magic_columns, :inherited_magic_columns unless method_defined? :magic_columns
|
34
|
-
|
35
|
-
# otherwise the calling model has the relationships
|
36
|
-
else
|
37
|
-
has_many :magic_column_relationships, :as => :owner, :dependent => :destroy
|
38
|
-
has_many :magic_columns, :through => :magic_column_relationships, :dependent => :destroy
|
39
|
-
end
|
40
|
-
|
41
|
-
# Hook into Base
|
42
|
-
class_eval do
|
43
|
-
alias_method :reload_without_magic, :reload
|
44
|
-
alias_method :create_or_update_without_magic, :create_or_update
|
45
|
-
alias_method :read_attribute_without_magic, :read_attribute
|
46
|
-
end
|
47
|
-
end
|
48
|
-
include InstanceMethods
|
49
|
-
|
50
|
-
# Add Magic to Base
|
51
|
-
alias_method :reload, :reload_with_magic
|
52
|
-
alias_method :read_attribute, :read_attribute_with_magic
|
53
|
-
alias_method :create_or_update, :create_or_update_with_magic
|
54
|
-
end
|
55
|
-
|
56
|
-
def magical?
|
57
|
-
self.included_modules.include?(InstanceMethods)
|
58
|
-
end
|
59
|
-
end
|
60
|
-
|
61
|
-
module InstanceMethods #:nodoc:
|
62
|
-
# Reinitialize MagicColumns and MagicAttributes when Model is reloaded
|
63
|
-
def reload_with_magic
|
64
|
-
initialize_magic_columns
|
65
|
-
reload_without_magic
|
66
|
-
end
|
67
|
-
|
68
|
-
def update_attributes(new_attributes)
|
69
|
-
attributes = new_attributes.stringify_keys
|
70
|
-
magic_attrs = magic_columns.map(&:name)
|
71
|
-
|
72
|
-
super(attributes.select{ |k, v| !magic_attrs.include?(k) })
|
73
|
-
attributes.select{ |k, v| magic_attrs.include?(k) }.each do |k, v|
|
74
|
-
col = find_magic_column_by_name(k)
|
75
|
-
attr = find_magic_attribute_by_column(col).first
|
76
|
-
attr.update_attributes(:value => v)
|
77
|
-
end
|
78
|
-
end
|
79
|
-
|
80
|
-
private
|
81
|
-
|
82
|
-
# Save MagicAttributes from @attributes
|
83
|
-
def create_or_update_with_magic
|
84
|
-
if result = create_or_update_without_magic
|
85
|
-
magic_columns.each do |column|
|
86
|
-
value = @attributes[column.name]
|
87
|
-
existing = find_magic_attribute_by_column(column)
|
88
|
-
|
89
|
-
unless column.datatype == 'check_box_multiple'
|
90
|
-
(attr = existing.first) ?
|
91
|
-
update_magic_attribute(attr, value) :
|
92
|
-
create_magic_attribute(column, value)
|
93
|
-
else
|
94
|
-
#TODO - make this more efficient
|
95
|
-
value = [value] unless value.is_a? Array
|
96
|
-
existing.map(&:destroy) if existing
|
97
|
-
value.collect {|v| create_magic_attribute(column, v)}
|
98
|
-
end
|
99
|
-
end
|
100
|
-
end
|
101
|
-
result
|
102
|
-
end
|
103
|
-
|
104
|
-
# Load (lazily) MagicAttributes or fall back
|
105
|
-
def method_missing(method_id, *args)
|
106
|
-
super(method_id, *args)
|
107
|
-
rescue NoMethodError
|
108
|
-
method_name = method_id.to_s
|
109
|
-
attr_names = magic_columns.map(&:name)
|
110
|
-
initialize_magic_columns and retry if attr_names.include?(method_name) or
|
111
|
-
(md = /[\?|\=]/.match(method_name) and
|
112
|
-
attr_names.include?(md.pre_match))
|
113
|
-
super(method_id, *args)
|
114
|
-
end
|
115
|
-
|
116
|
-
# Load the MagicAttribute(s) associated with attr_name and cast them to proper type.
|
117
|
-
def read_attribute_with_magic(attr_name)
|
118
|
-
return read_attribute_without_magic(attr_name) if column_for_attribute(attr_name) # filter for regular columns
|
119
|
-
attr_name = attr_name.to_s
|
120
|
-
|
121
|
-
if !(value = @attributes[attr_name]).nil?
|
122
|
-
if column = find_magic_column_by_name(attr_name)
|
123
|
-
if value.is_a? Array
|
124
|
-
value.map {|v| column.type_cast(v)}
|
125
|
-
else
|
126
|
-
column.type_cast(value)
|
127
|
-
end
|
128
|
-
else
|
129
|
-
value
|
130
|
-
end
|
131
|
-
else
|
132
|
-
nil
|
133
|
-
end
|
134
|
-
end
|
135
|
-
|
136
|
-
# Lookup all MagicAttributes and setup @attributes
|
137
|
-
def initialize_magic_columns
|
138
|
-
magic_columns.each do |column|
|
139
|
-
attribute = find_magic_attribute_by_column(column)
|
140
|
-
name = column.name
|
141
|
-
|
142
|
-
# Validation
|
143
|
-
self.class.validates_presence_of(name) if column.is_required?
|
144
|
-
|
145
|
-
# Write attribute
|
146
|
-
unless column.datatype == 'check_box_multiple'
|
147
|
-
(attr = attribute.first) ?
|
148
|
-
write_attribute(name, attr.to_s) :
|
149
|
-
write_attribute(name, column.default)
|
150
|
-
else
|
151
|
-
write_attribute(name, attribute.map(&:to_s))
|
152
|
-
end
|
153
|
-
end
|
154
|
-
end
|
155
|
-
|
156
|
-
def find_magic_attribute_by_column(column)
|
157
|
-
magic_attributes.to_a.find_all {|attr| attr.magic_column_id == column.id}
|
158
|
-
end
|
159
|
-
|
160
|
-
def find_magic_column_by_name(attr_name)
|
161
|
-
magic_columns.to_a.find {|column| column.name == attr_name}
|
162
|
-
end
|
163
|
-
|
164
|
-
def create_magic_attribute(magic_column, value)
|
165
|
-
magic_attributes << MagicAttribute.create(:magic_column => magic_column, :value => value)
|
166
|
-
end
|
167
|
-
|
168
|
-
def update_magic_attribute(magic_attribute, value)
|
169
|
-
magic_attribute.update_attributes(:value => value)
|
170
|
-
end
|
171
|
-
end
|
172
|
-
end
|