Commit 87d7ed404acf7ee97f4b1c5b6178a24bb73daed3
0 parents
Exists in
master
create from has_magic_columns
Showing
21 changed files
with
692 additions
and
0 deletions
Show diff stats
1 | +++ a/LICENSE.txt | |
... | ... | @@ -0,0 +1,22 @@ |
1 | +Copyright (c) 2014 ikeqiao | |
2 | + | |
3 | +MIT License | |
4 | + | |
5 | +Permission is hereby granted, free of charge, to any person obtaining | |
6 | +a copy of this software and associated documentation files (the | |
7 | +"Software"), to deal in the Software without restriction, including | |
8 | +without limitation the rights to use, copy, modify, merge, publish, | |
9 | +distribute, sublicense, and/or sell copies of the Software, and to | |
10 | +permit persons to whom the Software is furnished to do so, subject to | |
11 | +the following conditions: | |
12 | + | |
13 | +The above copyright notice and this permission notice shall be | |
14 | +included in all copies or substantial portions of the Software. | |
15 | + | |
16 | +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, | |
17 | +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | |
18 | +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND | |
19 | +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE | |
20 | +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION | |
21 | +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION | |
22 | +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | ... | ... |
1 | +++ a/README.md | |
... | ... | @@ -0,0 +1,29 @@ |
1 | +# HasMagicFields | |
2 | + | |
3 | +TODO: Write a gem description | |
4 | + | |
5 | +## Installation | |
6 | + | |
7 | +Add this line to your application's Gemfile: | |
8 | + | |
9 | + gem 'has_magic_fields' | |
10 | + | |
11 | +And then execute: | |
12 | + | |
13 | + $ bundle | |
14 | + | |
15 | +Or install it yourself as: | |
16 | + | |
17 | + $ gem install has_magic_fields | |
18 | + | |
19 | +## Usage | |
20 | + | |
21 | +TODO: Write usage instructions here | |
22 | + | |
23 | +## Contributing | |
24 | + | |
25 | +1. Fork it | |
26 | +2. Create your feature branch (`git checkout -b my-new-feature`) | |
27 | +3. Commit your changes (`git commit -am 'Add some feature'`) | |
28 | +4. Push to the branch (`git push origin my-new-feature`) | |
29 | +5. Create new Pull Request | ... | ... |
1 | +++ a/has_magic_fields.gemspec | |
... | ... | @@ -0,0 +1,25 @@ |
1 | +# coding: utf-8 | |
2 | +lib = File.expand_path('../lib', __FILE__) | |
3 | +$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib) | |
4 | +require 'has_magic_fields/version' | |
5 | + | |
6 | +Gem::Specification.new do |s| | |
7 | + s.name = "has_magic_fields" | |
8 | + s.version = HasMagicFields::VERSION | |
9 | + s.authors = ["ikeqiao"] | |
10 | + s.email = ["zhzsi@126.com"] | |
11 | + s.description = %q{TODO: Write a gem description} | |
12 | + s.summary = %q{TODO: Write a gem summary} | |
13 | + s.homepage = "" | |
14 | + s.license = "MIT" | |
15 | + | |
16 | + s.files = `git ls-files`.split($/) | |
17 | + s.executables = s.files.grep(%r{^bin/}) { |f| File.basename(f) } | |
18 | + s.test_files = s.files.grep(%r{^(test|s|features)/}) | |
19 | + s.require_paths = ["lib"] | |
20 | + | |
21 | + s.add_development_dependency "bundler", "~> 1.3" | |
22 | + s.add_development_dependency "rake" | |
23 | + s.add_dependency("rails", [">= 4.0.0"]) | |
24 | + | |
25 | +end | ... | ... |
lib/generators/has_magic_fields/install/install_generator.rb
0 → 100644
1 | +++ a/lib/generators/has_magic_fields/install/install_generator.rb | |
... | ... | @@ -0,0 +1,24 @@ |
1 | +require 'rails/generators/base' | |
2 | + | |
3 | +module HasMagicFields | |
4 | + class InstallGenerator < Rails::Generators::Base | |
5 | + include Rails::Generators::Migration | |
6 | + | |
7 | + source_root File.expand_path('../templates',__FILE__) | |
8 | + | |
9 | + desc "Add has_magic_fields migration." | |
10 | + | |
11 | + def self.next_migration_number(path) | |
12 | + unless @prev_migration_nr | |
13 | + @prev_migration_nr = Time.now.utc.strftime("%Y%m%d%H%M%S").to_i | |
14 | + else | |
15 | + @prev_migration_nr += 1 | |
16 | + end | |
17 | + @prev_migration_nr.to_s | |
18 | + end | |
19 | + | |
20 | + def add_migration | |
21 | + migration_template "migration.rb", "db/migrate/add_has_magic_fields_tables.rb" | |
22 | + end | |
23 | + end | |
24 | +end | ... | ... |
lib/generators/has_magic_fields/install/templates/migration.rb
0 → 100644
1 | +++ a/lib/generators/has_magic_fields/install/templates/migration.rb | |
... | ... | @@ -0,0 +1,51 @@ |
1 | +class AddHasMagicFieldsTables < ActiveRecord::Migration | |
2 | + def change | |
3 | + create_table :magic_fields do |t| | |
4 | + t.column :name, :string | |
5 | + t.column :pretty_name, :string | |
6 | + t.column :datatype, :string, :default => "string" | |
7 | + t.column :default, :string | |
8 | + t.column :is_required, :boolean, :default => false | |
9 | + t.column :include_blank, :boolean, :default => false | |
10 | + t.column :allow_other, :boolean, :default => true | |
11 | + t.column :created_at, :datetime | |
12 | + t.column :updated_at, :datetime | |
13 | + end | |
14 | + | |
15 | + create_table :magic_attributes do |t| | |
16 | + t.column :magic_field_id, :integer | |
17 | + t.column :magic_option_id, :integer | |
18 | + t.column :value, :string | |
19 | + t.column :created_at, :datetime | |
20 | + t.column :updated_at, :datetime | |
21 | + end | |
22 | + | |
23 | + create_table :magic_options do |t| | |
24 | + t.column :magic_field_id, :integer | |
25 | + t.column :value, :string | |
26 | + t.column :synonym, :string | |
27 | + t.column :created_at, :datetime | |
28 | + t.column :updated_at, :datetime | |
29 | + end | |
30 | + | |
31 | + create_table :magic_field_relationships do |t| | |
32 | + t.column :magic_field_id, :integer | |
33 | + t.column :owner_id, :integer | |
34 | + t.column :owner_type, :string | |
35 | + t.column :created_at, :datetime | |
36 | + t.column :updated_at, :datetime | |
37 | + end | |
38 | + | |
39 | + create_table :magic_attribute_relationships do |t| | |
40 | + t.column :magic_attribute_id, :integer | |
41 | + t.column :owner_id, :integer | |
42 | + t.column :owner_type, :string | |
43 | + end | |
44 | + | |
45 | + add_index :magic_attributes, [:magic_field_id, :magic_option_id], name:"attributes_column_option" | |
46 | + add_index :magic_attribute_relationships, [:magic_attribute_id, :owner_id], name:"magic_attribute_owner" | |
47 | + add_index :magic_field_relationships, [:magic_field_id, :owner_id], name:"magic_field_owner" | |
48 | + | |
49 | + end | |
50 | + | |
51 | +end | |
0 | 52 | \ No newline at end of file | ... | ... |
1 | +++ a/lib/has_magic_fields.rb | |
... | ... | @@ -0,0 +1,10 @@ |
1 | +require "has_magic_fields/version" | |
2 | +require "has_magic_fields/models/magic_attribute" | |
3 | +require "has_magic_fields/models/magic_field" | |
4 | +require "has_magic_fields/models/magic_option" | |
5 | +require "has_magic_fields/models/magic_attribute_relationship" | |
6 | +require "has_magic_fields/models/magic_field_relationship" | |
7 | +require "has_magic_fields/extend" | |
8 | + | |
9 | + | |
10 | + | ... | ... |
1 | +++ a/lib/has_magic_fields/extend.rb | |
... | ... | @@ -0,0 +1,173 @@ |
1 | +module HasMagicFields | |
2 | + module Extend extend ActiveSupport::Concern | |
3 | + module ClassMethods | |
4 | + def has_magic_fields(options = {}) | |
5 | + # Associations | |
6 | + has_many :magic_attribute_relationships, :as => :owner, :dependent => :destroy | |
7 | + has_many :magic_attributes, :through => :magic_attribute_relationships, :dependent => :destroy | |
8 | + | |
9 | + # Eager loading - EXPERIMENTAL! | |
10 | + if options[:eager] | |
11 | + class_eval do | |
12 | + def after_initialize | |
13 | + initialize_magic_fields | |
14 | + end | |
15 | + end | |
16 | + end | |
17 | + | |
18 | + # Inheritence | |
19 | + cattr_accessor :inherited_from | |
20 | + | |
21 | + # if options[:through] is supplied, treat as an inherited relationship | |
22 | + if self.inherited_from = options[:through] | |
23 | + class_eval do | |
24 | + def inherited_magic_fields | |
25 | + raise "Cannot inherit MagicFields from a non-existant association: #{@inherited_from}" unless self.class.method_defined?(inherited_from)# and self.send(inherited_from) | |
26 | + self.send(inherited_from).magic_fields | |
27 | + end | |
28 | + end | |
29 | + alias_method :magic_fields, :inherited_magic_fields unless method_defined? :magic_fields | |
30 | + | |
31 | + # otherwise the calling model has the relationships | |
32 | + else | |
33 | + has_many :magic_field_relationships, :as => :owner, :dependent => :destroy | |
34 | + has_many :magic_fields, :through => :magic_field_relationships, :dependent => :destroy | |
35 | + end | |
36 | + | |
37 | + # # Hook into Base | |
38 | + class_eval do | |
39 | + alias_method :reload_without_magic, :reload | |
40 | + alias_method :create_or_update_without_magic, :create_or_update | |
41 | + alias_method :read_attribute_without_magic, :read_attribute | |
42 | + end | |
43 | + | |
44 | + | |
45 | + # Add Magic to Base | |
46 | + alias_method :reload, :reload_with_magic | |
47 | + alias_method :read_attribute, :read_attribute_with_magic | |
48 | + alias_method :create_or_update, :create_or_update_with_magic | |
49 | + end | |
50 | + end | |
51 | + | |
52 | + included do | |
53 | + # Reinitialize MagicFields and MagicAttributes when Model is reloaded | |
54 | + def reload_with_magic | |
55 | + initialize_magic_fields | |
56 | + reload_without_magic | |
57 | + end | |
58 | + | |
59 | + def update_attributes(new_attributes) | |
60 | + attributes = new_attributes.stringify_keys | |
61 | + magic_attrs = magic_fields.map(&:name) | |
62 | + | |
63 | + super(attributes.select{ |k, v| !magic_attrs.include?(k) }) | |
64 | + attributes.select{ |k, v| magic_attrs.include?(k) }.each do |k, v| | |
65 | + col = find_magic_field_by_name(k) | |
66 | + attr = find_magic_attribute_by_column(col).first | |
67 | + attr.update_attributes(:value => v) | |
68 | + end | |
69 | + end | |
70 | + | |
71 | + private | |
72 | + | |
73 | + # Save MagicAttributes from @attributes | |
74 | + def create_or_update_with_magic | |
75 | + if result = create_or_update_without_magic | |
76 | + magic_fields.each do |column| | |
77 | + value = @attributes[column.name] | |
78 | + existing = find_magic_attribute_by_column(column) | |
79 | + | |
80 | + unless column.datatype == 'check_box_multiple' | |
81 | + (attr = existing.first) ? | |
82 | + update_magic_attribute(attr, value) : | |
83 | + create_magic_attribute(column, value) | |
84 | + else | |
85 | + #TODO - make this more efficient | |
86 | + value = [value] unless value.is_a? Array | |
87 | + existing.map(&:destroy) if existing | |
88 | + value.collect {|v| create_magic_attribute(column, v)} | |
89 | + end | |
90 | + end | |
91 | + end | |
92 | + result | |
93 | + end | |
94 | + | |
95 | + # Load (lazily) MagicAttributes or fall back | |
96 | + def method_missing(method_id, *args) | |
97 | + super(method_id, *args) | |
98 | + rescue NoMethodError | |
99 | + method_name = method_id.to_s | |
100 | + attr_names = magic_fields.map(&:name) | |
101 | + initialize_magic_fields and retry if attr_names.include?(method_name) or | |
102 | + (md = /[\?|\=]/.match(method_name) and | |
103 | + attr_names.include?(md.pre_match)) | |
104 | + super(method_id, *args) | |
105 | + end | |
106 | + | |
107 | + # Load the MagicAttribute(s) associated with attr_name and cast them to proper type. | |
108 | + def read_attribute_with_magic(attr_name) | |
109 | + return read_attribute_without_magic(attr_name) if column_for_attribute(attr_name) # filter for regular columns | |
110 | + attr_name = attr_name.to_s | |
111 | + | |
112 | + if !(value = @attributes[attr_name]).nil? | |
113 | + if column = find_magic_field_by_name(attr_name) | |
114 | + if value.is_a? Array | |
115 | + value.map {|v| column.type_cast(v)} | |
116 | + else | |
117 | + column.type_cast(value) | |
118 | + end | |
119 | + else | |
120 | + value | |
121 | + end | |
122 | + else | |
123 | + nil | |
124 | + end | |
125 | + end | |
126 | + | |
127 | + # Lookup all MagicAttributes and setup @attributes | |
128 | + def initialize_magic_fields | |
129 | + magic_fields.each do |column| | |
130 | + attribute = find_magic_attribute_by_column(column) | |
131 | + name = column.name | |
132 | + | |
133 | + # Validation | |
134 | + self.class.validates_presence_of(name) if column.is_required? | |
135 | + | |
136 | + # Write attribute | |
137 | + unless column.datatype == 'check_box_multiple' | |
138 | + (attr = attribute.first) ? | |
139 | + write_magic_attribute(name, attr.to_s) : | |
140 | + write_magic_attribute(name, column.default) | |
141 | + else | |
142 | + write_magic_attribute(name, attribute.map(&:to_s)) | |
143 | + end | |
144 | + end | |
145 | + end | |
146 | + | |
147 | + | |
148 | + def write_magic_attribute(magic_attribute, value) | |
149 | + @attributes[magic_attribute] = value | |
150 | + @attributes_cache[magic_attribute] = value | |
151 | + end | |
152 | + | |
153 | + def find_magic_attribute_by_column(column) | |
154 | + magic_attributes.to_a.find_all {|attr| attr.magic_field_id == column.id} | |
155 | + end | |
156 | + | |
157 | + def find_magic_field_by_name(attr_name) | |
158 | + magic_fields.to_a.find {|column| column.name == attr_name} | |
159 | + end | |
160 | + | |
161 | + def create_magic_attribute(magic_field, value) | |
162 | + magic_attributes << MagicAttribute.create(:magic_field => magic_field, :value => value) | |
163 | + end | |
164 | + | |
165 | + def update_magic_attribute(magic_attribute, value) | |
166 | + magic_attribute.update_attributes(:value => value) | |
167 | + end | |
168 | + end | |
169 | + | |
170 | + end | |
171 | +end | |
172 | + | |
173 | + | ... | ... |
1 | +++ a/lib/has_magic_fields/models/magic_attribute.rb | |
... | ... | @@ -0,0 +1,29 @@ |
1 | +# Always work through the interface MagicAttribute.value | |
2 | +class MagicAttribute < ActiveRecord::Base | |
3 | + belongs_to :magic_field | |
4 | + belongs_to :magic_option | |
5 | + | |
6 | + before_save :update_magic | |
7 | + | |
8 | + def to_s | |
9 | + (magic_option) ? magic_option.value : value | |
10 | + end | |
11 | + | |
12 | + def update_magic | |
13 | + if option = find_magic_option_for(value) | |
14 | + unless magic_option and magic_option == option | |
15 | + self.value = nil | |
16 | + self.magic_option = option | |
17 | + end | |
18 | + elsif magic_field.allow_other | |
19 | + self.magic_option = nil | |
20 | + end | |
21 | + end | |
22 | + | |
23 | +private | |
24 | + | |
25 | + def find_magic_option_for(value) | |
26 | + magic_field.magic_options.find(:first, | |
27 | + :conditions => ["value = ? or synonym = ?", value, value]) unless magic_field.nil? or magic_field.magic_options.blank? | |
28 | + end | |
29 | +end | ... | ... |
lib/has_magic_fields/models/magic_attribute_relationship.rb
0 → 100644
1 | +++ a/lib/has_magic_fields/models/magic_field.rb | |
... | ... | @@ -0,0 +1,54 @@ |
1 | +class MagicField < ActiveRecord::Base | |
2 | + has_many :magic_field_relationships | |
3 | + has_many :owners, :through => :magic_field_relationships, :as => :owner | |
4 | + has_many :magic_options | |
5 | + has_many :magic_attributes, :dependent => :destroy | |
6 | + | |
7 | + validates_presence_of :name, :datatype | |
8 | + validates_format_of :name, :with => /\A[a-z][a-z0-9_]+\z/ | |
9 | + | |
10 | + def type_cast(value) | |
11 | + begin | |
12 | + case datatype.to_sym | |
13 | + when :check_box_boolean | |
14 | + (value.to_int == 1) ? true : false | |
15 | + when :date | |
16 | + Date.parse(value) | |
17 | + when :datetime | |
18 | + Time.parse(value) | |
19 | + when :integer | |
20 | + value.to_int | |
21 | + else | |
22 | + value | |
23 | + end | |
24 | + rescue | |
25 | + value | |
26 | + end | |
27 | + end | |
28 | + | |
29 | + # Display a nicer (possibly user-defined) name for the column or use a fancified default. | |
30 | + def pretty_name | |
31 | + super || name.humanize | |
32 | + end | |
33 | + | |
34 | + #get or set a variable with the variable as the called method | |
35 | + def self.method_missing(method, *args) | |
36 | + debugger | |
37 | + | |
38 | + method_name = method.to_s | |
39 | + super(method, *args) | |
40 | + rescue NoMethodError | |
41 | + debugger | |
42 | + #set a value for a variable | |
43 | + if method_name =~ /=$/ | |
44 | + var_name = method_name.gsub('=', '') | |
45 | + value = args.first | |
46 | + self[var_name] = value | |
47 | + #retrieve a value | |
48 | + else | |
49 | + self[method_name] | |
50 | + end | |
51 | + end | |
52 | + | |
53 | + | |
54 | +end | ... | ... |
1 | +++ a/lib/has_magic_fields/models/magic_option.rb | |
... | ... | @@ -0,0 +1,7 @@ |
1 | +class MagicOption < ActiveRecord::Base | |
2 | + belongs_to :magic_field | |
3 | + | |
4 | + validates_presence_of :value | |
5 | + validates_uniqueness_of :value, :scope => :magic_field_id | |
6 | + validates_uniqueness_of :synonym, :scope => :magic_field_id, :if => Proc.new{|this| !this.synonym.nil? and !this.synonym.empty?} | |
7 | +end | |
0 | 8 | \ No newline at end of file | ... | ... |
1 | +++ a/spec/has_magic_fields/magic_fileds_spec.rb | |
... | ... | @@ -0,0 +1,105 @@ |
1 | +require 'spec_helper' | |
2 | + | |
3 | + | |
4 | +describe HasMagicFields do | |
5 | + | |
6 | + context "on a single model" do | |
7 | + before(:each) do | |
8 | + @charlie = Person.create(name: "charlie") | |
9 | + end | |
10 | + | |
11 | + it "initializes magic fields correctly" do | |
12 | + expect(@charlie).not_to be(nil) | |
13 | + expect(@charlie.class).to be(Person) | |
14 | + expect(@charlie.magic_fields).not_to be(nil) | |
15 | + end | |
16 | + | |
17 | + it "allows adding a magic field" do | |
18 | + @charlie.magic_fields.create(:name => 'salary') | |
19 | + expect(@charlie.magic_fields.length).to be(1) | |
20 | + end | |
21 | + | |
22 | + it "allows setting and saving of magic attributes" do | |
23 | + @charlie.magic_fields.create(:name => 'salary') | |
24 | + @charlie.salary = 50000 | |
25 | + @charlie.save | |
26 | + @charlie = Person.find(@charlie.id) | |
27 | + expect(@charlie.salary).not_to be(nil) | |
28 | + end | |
29 | + | |
30 | + # it "forces required if is_required is true" do | |
31 | + # # TODO figure out why this fails | |
32 | + # @charlie.magic_fields.create(:name => "last_name", :is_required => true) | |
33 | + # expect(@charlie.save).to be(false) | |
34 | + # end | |
35 | + | |
36 | + it "allows datatype to be :date" do | |
37 | + @charlie.magic_fields.create(:name => "birthday", :datatype => :date) | |
38 | + @charlie.birthday = Date.today | |
39 | + expect(@charlie.save).to be(true) | |
40 | + end | |
41 | + | |
42 | + it "allows datatype to be :datetime" do | |
43 | + @charlie.magic_fields.create(:name => "signed_up_at", :datatype => :datetime) | |
44 | + @charlie.signed_up_at = DateTime.now | |
45 | + expect(@charlie.save).to be(true) | |
46 | + end | |
47 | + | |
48 | + it "allows datatype to be :integer" do | |
49 | + @charlie.magic_fields.create(:name => "age", :datatype => :integer) | |
50 | + @charlie.age = 5 | |
51 | + expect(@charlie.save).to be(true) | |
52 | + end | |
53 | + | |
54 | + it "allows datatype to be :check_box_boolean" do | |
55 | + @charlie.magic_fields.create(:name => "retired", :datatype => :check_box_boolean) | |
56 | + @charlie.retired = false | |
57 | + expect(@charlie.save).to be(true) | |
58 | + end | |
59 | + | |
60 | + it "allows default to be set" do | |
61 | + @charlie.magic_fields.create(:name => "bonus", :default => "40000") | |
62 | + expect(@charlie.bonus).to eq("40000") | |
63 | + end | |
64 | + | |
65 | + it "allows a pretty display name to be set" do | |
66 | + @charlie.magic_fields.create(:name => "zip", :pretty_name => "Zip Code") | |
67 | + expect(@charlie.magic_fields.last.pretty_name).to eq("Zip Code") | |
68 | + end | |
69 | + end | |
70 | + | |
71 | + context "in a parent-child relationship" do | |
72 | + before(:each) do | |
73 | + @account = Account.create(name:"important") | |
74 | + @alice = User.create(name:"alice", account: @account ) | |
75 | + end | |
76 | + | |
77 | + it "initializes magic fields correctly" do | |
78 | + expect(@alice).not_to be(nil) | |
79 | + expect(@alice.class).to be(User) | |
80 | + expect(@alice.magic_fields).not_to be(nil) | |
81 | + | |
82 | + expect(@account).not_to be(nil) | |
83 | + expect(@account.class).to be(Account) | |
84 | + expect(@alice.magic_fields).not_to be(nil) | |
85 | + end | |
86 | + | |
87 | + it "allows adding a magic field to the child" do | |
88 | + @alice.magic_fields.create(:name => 'salary') | |
89 | + expect(lambda{@alice.salary}).not_to raise_error | |
90 | + expect(lambda{@account.reload_with_magic.salary}).not_to raise_error | |
91 | + end | |
92 | + | |
93 | + it "allows adding a magic field to the parent" do | |
94 | + @account.magic_fields.create(:name => 'age') | |
95 | + expect(lambda{@alice.reload_with_magic.age}).not_to raise_error | |
96 | + end | |
97 | + | |
98 | + it "sets magic fields for all child models" do | |
99 | + @bob = User.create(name:"bob", account: @account ) | |
100 | + @bob.magic_fields.create(:name => 'birthday') | |
101 | + @alice.reload_with_magic | |
102 | + expect(lambda{@alice.birthday}).not_to raise_error | |
103 | + end | |
104 | + end | |
105 | +end | ... | ... |
1 | +++ a/spec/spec_helper.rb | |
... | ... | @@ -0,0 +1,108 @@ |
1 | +require 'rubygems' | |
2 | +require "active_record" | |
3 | +require 'active_support' | |
4 | +require 'sqlite3' | |
5 | +require 'active_record/fixtures' | |
6 | +require 'debugger' | |
7 | + | |
8 | + | |
9 | +$LOAD_PATH.unshift(File.dirname(__FILE__)) | |
10 | +$LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'rails')) | |
11 | +require "init" | |
12 | + | |
13 | +require "rails/railtie" | |
14 | + | |
15 | +# ActiveRecord::Base.logger = Logger.new(STDOUT) | |
16 | +ActiveRecord::Base.establish_connection(:adapter => "sqlite3", :database => ":memory:") | |
17 | +# ActiveRecord::Base.configurations = true | |
18 | + | |
19 | +ActiveRecord::Schema.verbose = false | |
20 | + | |
21 | +ActiveRecord::Schema.define do | |
22 | + | |
23 | + create_table "users", :force => true do |t| | |
24 | + t.column "name", :text | |
25 | + t.column "account_id", :integer | |
26 | + end | |
27 | + | |
28 | + create_table "accounts", :force => true do |t| | |
29 | + t.column "name", :text | |
30 | + end | |
31 | + | |
32 | + create_table "people", :force => true do |t| | |
33 | + t.column "name", :text | |
34 | + end | |
35 | + | |
36 | + | |
37 | + # Has Magic Columns migration generator output | |
38 | + | |
39 | + create_table :magic_fields do |t| | |
40 | + t.column :name, :string | |
41 | + t.column :pretty_name, :string | |
42 | + t.column :datatype, :string, :default => "string" | |
43 | + t.column :default, :string | |
44 | + t.column :is_required, :boolean, :default => false | |
45 | + t.column :include_blank, :boolean, :default => false | |
46 | + t.column :allow_other, :boolean, :default => true | |
47 | + t.column :created_at, :datetime | |
48 | + t.column :updated_at, :datetime | |
49 | + end | |
50 | + | |
51 | + create_table :magic_attributes do |t| | |
52 | + t.column :magic_field_id, :integer | |
53 | + t.column :magic_option_id, :integer | |
54 | + t.column :value, :string | |
55 | + t.column :created_at, :datetime | |
56 | + t.column :updated_at, :datetime | |
57 | + end | |
58 | + | |
59 | + create_table :magic_options do |t| | |
60 | + t.column :magic_field_id, :integer | |
61 | + t.column :value, :string | |
62 | + t.column :synonym, :string | |
63 | + t.column :created_at, :datetime | |
64 | + t.column :updated_at, :datetime | |
65 | + end | |
66 | + | |
67 | + create_table :magic_field_relationships do |t| | |
68 | + t.column :magic_field_id, :integer | |
69 | + t.column :owner_id, :integer | |
70 | + t.column :owner_type, :string | |
71 | + t.column :created_at, :datetime | |
72 | + t.column :updated_at, :datetime | |
73 | + end | |
74 | + | |
75 | + create_table :magic_attribute_relationships do |t| | |
76 | + t.column :magic_attribute_id, :integer | |
77 | + t.column :owner_id, :integer | |
78 | + t.column :owner_type, :string | |
79 | + end | |
80 | + | |
81 | +end | |
82 | + | |
83 | + | |
84 | +RSpec.configure do |config| | |
85 | + | |
86 | + config.before(:all) do | |
87 | + class Account < ActiveRecord::Base | |
88 | + include HasMagicFields::Extend | |
89 | + has_many :users | |
90 | + has_magic_fields | |
91 | + end | |
92 | + | |
93 | + class Person < ActiveRecord::Base | |
94 | + include HasMagicFields::Extend | |
95 | + has_magic_fields | |
96 | + end | |
97 | + | |
98 | + class User < ActiveRecord::Base | |
99 | + include HasMagicFields::Extend | |
100 | + belongs_to :account | |
101 | + has_magic_fields :through => :account | |
102 | + end | |
103 | + end | |
104 | + | |
105 | + config.after(:all) do | |
106 | + end | |
107 | +end | |
108 | + | ... | ... |