has_magic_columns 0.1.2 → 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|