has_alter_ego 0.0.4 → 0.0.5

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/Changelog.md CHANGED
@@ -1,3 +1,10 @@
1
+ # 0.0.5 (2010-06-13)
2
+ * Implemented smart associations, e.g.
3
+ category_by_name: Sport # => @car.category = Category.find_by_name("Sport")
4
+ sellers_by_name_and_active: [Hugo, true] # @car.sellers = Seller.find_all_by_name_and_active("Hugo", true)
5
+ sellers_by_name_and_active: [[Hugo, Egon], true] # @car.sellers = Seller.find_all_by_name_and_active(["Hugo", "Egon"], true)
6
+ * mark objects as modified when saved with save!
7
+
1
8
  # 0.0.4 (2010-06-11)
2
9
  * fix some bugs esp. wrt associations
3
10
  * added a on_seed hook which allows for custom login on seed
data/README.md CHANGED
@@ -124,6 +124,24 @@ If you don't want to inherit changes for an object without actually modifying it
124
124
  @car.alter_ego_state
125
125
  => "default"
126
126
 
127
+ # Smart associations
128
+
129
+ It's possible to define dynamic associations in the seed data which is helpful if the IDs of the associated objects are
130
+ not known or the associations depends on the state of the objects. This is done by appending *_by* clauses to the
131
+ association name, similar to the dynamic finders in ActiveRecord::Base.
132
+
133
+ **Example:**
134
+ db/fixtures/car.yml:
135
+ 1:
136
+ brand: Lotus
137
+ model: Elise
138
+ category_id: 3 # Static way of specifying associations
139
+ category_by_name: Sport # => @car.category = Category.find_by_name("Sport")
140
+
141
+ sellers_by_name_and_active: [Hugo, true] # @car.sellers = Seller.find_all_by_name_and_active("Hugo", true)
142
+ sellers_by_name_and_active: [[Hugo, Egon], true] # @car.sellers = Seller.find_all_by_name_and_active(["Hugo", "Egon"], true)
143
+
144
+
127
145
  # Custom logic on seed
128
146
 
129
147
  has_alter_ego provides a hook for adding custom logic when an object is created or updated from the seed definitions.
data/lib/has_alter_ego.rb CHANGED
@@ -46,10 +46,7 @@ module HasAlterEgo
46
46
  if db_object
47
47
  raise "There is already a #{db_object.class} with id #{db_object.id} in the database." unless db_object.has_alter_ego?
48
48
  if db_object.alter_ego.state == 'default'
49
- yml[primary_key].keys.each do |attr|
50
- next unless db_object.respond_to?(attr)
51
- db_object.send(attr+"=", yml[primary_key][attr])
52
- end
49
+ assign_attributes db_object, yml[primary_key]
53
50
  db_object.on_seed(yml[primary_key])
54
51
  db_object.save_without_alter_ego
55
52
  end
@@ -60,10 +57,7 @@ module HasAlterEgo
60
57
 
61
58
  db_object = self.new
62
59
  db_object[self.primary_key] = primary_key
63
- yml[primary_key].keys.each do |attr|
64
- next unless db_object.respond_to?(attr)
65
- db_object.send(attr+"=" , yml[primary_key][attr])
66
- end
60
+ assign_attributes db_object, yml[primary_key]
67
61
  db_object.build_alter_ego
68
62
  db_object.alter_ego.state = 'default'
69
63
  db_object.on_seed(yml[primary_key])
@@ -71,7 +65,25 @@ module HasAlterEgo
71
65
  end
72
66
  end
73
67
 
74
- private
68
+ def assign_attributes obj, yml
69
+ reflections = self.reflect_on_all_associations
70
+ yml.keys.each do |attr|
71
+ if obj.respond_to?(attr)
72
+ obj.send(attr+"=" , yml[attr])
73
+ else
74
+ # Handle smart associations
75
+ reflections.select{|r| attr.start_with?(r.name.to_s+"_by_")}.each do |r|
76
+ finder = [:has_one, :belongs_to].include?(r.macro) ? "find" : "find_all"
77
+ if attr.index("_and_")
78
+ objects = r.klass.send(attr.gsub(r.name.to_s, finder), *(yml[attr]))
79
+ else
80
+ objects = r.klass.send(attr.gsub(r.name.to_s, finder), yml[attr])
81
+ end
82
+ obj.send(r.name.to_s+"=", objects) if objects.present?
83
+ end
84
+ end
85
+ end
86
+ end
75
87
 
76
88
  def get_yml
77
89
  filename = File.join(RAILS_ROOT, "db", "fixtures", "alter_egos", self.table_name + ".yml")
@@ -103,6 +115,10 @@ module HasAlterEgo
103
115
  save_without_alter_ego perform_validation
104
116
  end
105
117
 
118
+ def save!
119
+ save || raise(RecordNotSaved)
120
+ end
121
+
106
122
  def destroy
107
123
  if self.alter_ego
108
124
  self.alter_ego.state = 'destroyed'
@@ -2,4 +2,7 @@
2
2
  name: Bruno
3
3
 
4
4
  2:
5
- name: Harald
5
+ name: Harald
6
+
7
+ 3:
8
+ name: Hugo
@@ -1,36 +1,5 @@
1
1
  require 'test_helper'
2
2
 
3
-
4
- class Seller < ActiveRecord::Base
5
- has_and_belongs_to_many :cars
6
- has_alter_ego
7
- end
8
-
9
- class Car < ActiveRecord::Base
10
- has_many :tires
11
- has_and_belongs_to_many :sellers
12
- has_alter_ego
13
- attr_accessor :tires_count
14
-
15
- def on_seed attributes
16
- self[:tires_count] = attributes["custom_data"]["tires"] if attributes["custom_data"]
17
- end
18
- end
19
-
20
- class Bike < ActiveRecord::Base
21
- end
22
-
23
- class Scooter < ActiveRecord::Base
24
- end
25
-
26
- class Tire < ActiveRecord::Base
27
- end
28
-
29
- class Drink < ActiveRecord::Base
30
- set_primary_key :name
31
- has_alter_ego
32
- end
33
-
34
3
  class HasAlterEgoTest < Test::Unit::TestCase
35
4
  def test_space_gets_reserved
36
5
  c = Car.create
@@ -206,4 +175,68 @@ class HasAlterEgoTest < Test::Unit::TestCase
206
175
 
207
176
  assert_equal [1,2], c.seller_ids
208
177
  end
178
+
179
+ def test_smart_habtm
180
+ Car.destroy_all
181
+ AlterEgo.find_all_by_alter_ego_object_type("Car").map(&:destroy)
182
+ Car.class_eval do
183
+ def self.get_yml
184
+ return {1 => {
185
+ "brand" => "Lotus",
186
+ "model" => "Elise",
187
+ "sellers_by_name" => ["Harald", "Hugo"]}}
188
+ end
189
+ end
190
+ Car.parse_yml
191
+ assert_equal 1, Car.count
192
+ assert_equal 2, Car.first.sellers.size
193
+ assert_equal [2,3].sort, Car.first.seller_ids.sort
194
+ end
195
+
196
+ def test_smart_has_many
197
+ Light.create(:color => "blue", :active => true)
198
+ Light.create(:color => "yellow", :active => true)
199
+ Light.create(:color => "red", :active => true)
200
+ Light.create(:color => "green", :active => false)
201
+ Bike.destroy_all
202
+ Bike.class_eval do
203
+ def self.get_yml
204
+ return {1 => {
205
+ "lights_by_color_and_active" => [["blue", "yellow", "green"], true]}}
206
+ end
207
+ end
208
+ Bike.parse_yml
209
+ assert_equal 1, Bike.count
210
+ assert_equal 2, Bike.first.lights.size
211
+ assert_equal Light.find_all_by_color(["blue", "yellow"]), Bike.first.lights
212
+ end
213
+
214
+ def test_smart_has_one
215
+ Creator.create(:name => "Martin")
216
+ Creator.create(:name => "Mike")
217
+ Drink.destroy_all
218
+ Drink.class_eval do
219
+ def self.get_yml
220
+ return {1 => {
221
+ "creator_by_name" => ["Mike"]}}
222
+ end
223
+ end
224
+ Drink.parse_yml
225
+ assert_equal 1, Drink.count
226
+ assert_equal Creator.find_by_name("Mike"), Drink.first.creator
227
+ end
228
+
229
+ def test_smart_belongs_to
230
+
231
+ Creator.class_eval do
232
+ def self.get_yml
233
+ return {1 => {
234
+ "name" => "Bernd",
235
+ "drink_by_name" => "water"}}
236
+ end
237
+ end
238
+ Creator.parse_yml
239
+ c = Creator.find_by_name "Bernd"
240
+ assert_equal Drink.find_by_name("water"), c.drink
241
+ end
209
242
  end
data/test/test_helper.rb CHANGED
@@ -25,6 +25,12 @@ silence_stream(STDOUT) do
25
25
  create_table :bikes
26
26
  create_table :scooters
27
27
 
28
+ create_table :lights do |t|
29
+ t.string :color
30
+ t.boolean :active
31
+ t.integer :bike_id
32
+ end
33
+
28
34
  create_table :tires do |t|
29
35
  t.integer :car_id
30
36
  end
@@ -34,6 +40,11 @@ silence_stream(STDOUT) do
34
40
  t.string :color
35
41
  end
36
42
 
43
+ create_table :creators do |t|
44
+ t.string :name
45
+ t.string :drink_id
46
+ end
47
+
37
48
  create_table :sellers do |t|
38
49
  t.string :name
39
50
  end
@@ -43,4 +54,45 @@ silence_stream(STDOUT) do
43
54
  end
44
55
 
45
56
  end
57
+ end
58
+
59
+
60
+ class Seller < ActiveRecord::Base
61
+ has_and_belongs_to_many :cars
62
+ has_alter_ego
63
+ end
64
+
65
+ class Car < ActiveRecord::Base
66
+ has_many :tires
67
+ has_and_belongs_to_many :sellers
68
+ has_alter_ego
69
+ attr_accessor :tires_count
70
+
71
+ def on_seed attributes
72
+ self[:tires_count] = attributes["custom_data"]["tires"] if attributes["custom_data"]
73
+ end
74
+ end
75
+
76
+ class Bike < ActiveRecord::Base
77
+ has_many :lights
78
+ end
79
+
80
+ class Scooter < ActiveRecord::Base
81
+ end
82
+
83
+ class Light < ActiveRecord::Base
84
+ end
85
+
86
+ class Tire < ActiveRecord::Base
87
+ end
88
+
89
+ class Drink < ActiveRecord::Base
90
+ set_primary_key :name
91
+ has_one :creator
92
+ has_alter_ego
93
+ end
94
+
95
+ class Creator < ActiveRecord::Base
96
+ belongs_to :drink
97
+ has_alter_ego
46
98
  end
metadata CHANGED
@@ -1,13 +1,12 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: has_alter_ego
3
3
  version: !ruby/object:Gem::Version
4
- hash: 23
5
4
  prerelease: false
6
5
  segments:
7
6
  - 0
8
7
  - 0
9
- - 4
10
- version: 0.0.4
8
+ - 5
9
+ version: 0.0.5
11
10
  platform: ruby
12
11
  authors:
13
12
  - "Andr\xC3\xA9 Duffeck"
@@ -15,7 +14,7 @@ autorequire:
15
14
  bindir: bin
16
15
  cert_chain: []
17
16
 
18
- date: 2010-06-11 00:00:00 +02:00
17
+ date: 2010-06-13 00:00:00 +02:00
19
18
  default_executable:
20
19
  dependencies: []
21
20
 
@@ -29,24 +28,24 @@ extensions: []
29
28
  extra_rdoc_files: []
30
29
 
31
30
  files:
32
- - lib/has_alter_ego/alter_ego.rb
33
- - lib/has_alter_ego/dumper.rb
34
31
  - lib/generators/has_alter_ego_generator.rb
35
32
  - lib/has_alter_ego.rb
33
+ - lib/has_alter_ego/dumper.rb
34
+ - lib/has_alter_ego/alter_ego.rb
36
35
  - lib/tasks/has_alter_ego.rake
37
- - Changelog.md
38
36
  - README.md
37
+ - Changelog.md
39
38
  - Rakefile
40
39
  - rails/init.rb
41
40
  - generators/has_alter_ego/templates/create_alter_egos.rb
42
41
  - generators/has_alter_ego/has_alter_ego_generator.rb
42
+ - test/db/fixtures/alter_egos/drinks.yml
43
+ - test/db/fixtures/alter_egos/cars.yml
43
44
  - test/db/fixtures/alter_egos/sellers.yml
44
45
  - test/db/fixtures/alter_egos/bikes.yml
45
- - test/db/fixtures/alter_egos/cars.yml
46
- - test/db/fixtures/alter_egos/drinks.yml
47
46
  - test/test_helper.rb
48
47
  - test/has_alter_ego_test.rb
49
- has_rdoc: false
48
+ has_rdoc: true
50
49
  homepage: http://github.com/aduffeck/has_alter_ego
51
50
  licenses: []
52
51
 
@@ -56,27 +55,23 @@ rdoc_options: []
56
55
  require_paths:
57
56
  - lib
58
57
  required_ruby_version: !ruby/object:Gem::Requirement
59
- none: false
60
58
  requirements:
61
59
  - - ">="
62
60
  - !ruby/object:Gem::Version
63
- hash: 3
64
61
  segments:
65
62
  - 0
66
63
  version: "0"
67
64
  required_rubygems_version: !ruby/object:Gem::Requirement
68
- none: false
69
65
  requirements:
70
66
  - - ">="
71
67
  - !ruby/object:Gem::Version
72
- hash: 3
73
68
  segments:
74
69
  - 0
75
70
  version: "0"
76
71
  requirements: []
77
72
 
78
73
  rubyforge_project:
79
- rubygems_version: 1.3.7
74
+ rubygems_version: 1.3.6
80
75
  signing_key:
81
76
  specification_version: 3
82
77
  summary: A Rails plugin which makes it possible to keep seed and live data in parallel