meta_where 0.9.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.
@@ -0,0 +1,30 @@
1
+ module MetaWhere
2
+ class Compound
3
+ attr_reader :condition1, :condition2
4
+
5
+ def initialize(condition1, condition2)
6
+ @condition1 = condition1
7
+ @condition2 = condition2
8
+ end
9
+
10
+ def |(other)
11
+ Or.new(self, other)
12
+ end
13
+
14
+ def &(other)
15
+ And.new(self, other)
16
+ end
17
+ end
18
+
19
+ class Or < Compound
20
+ def to_predicate(builder, parent = nil)
21
+ condition1.to_predicate(builder, parent).or(condition2.to_predicate(builder, parent))
22
+ end
23
+ end
24
+
25
+ class And < Compound
26
+ def to_predicate(builder, parent = nil)
27
+ condition1.to_predicate(builder, parent).and(condition2.to_predicate(builder, parent))
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,51 @@
1
+ require 'meta_where/utility'
2
+
3
+ module MetaWhere
4
+ class Condition
5
+ include MetaWhere::Utility
6
+
7
+ attr_reader :column, :value, :method
8
+
9
+ def initialize(column, value, method)
10
+ @column = column.to_s
11
+ @value = value
12
+ @method = (MetaWhere::METHOD_ALIASES[method.to_s] || method).to_s
13
+ end
14
+
15
+ def to_predicate(builder, parent = nil)
16
+ table = builder.build_table(parent)
17
+
18
+ unless attribute = table[column]
19
+ raise ::ActiveRecord::StatementInvalid, "No attribute named `#{column}` exists for table `#{table.name}`"
20
+ end
21
+
22
+ unless valid_comparison_method?(method)
23
+ raise ::ActiveRecord::StatementInvalid, "No comparison method named `#{method}` exists for column `#{column}`"
24
+ end
25
+ attribute.send(method, *args_for_predicate(method.to_s, value))
26
+ end
27
+
28
+ def ==(other_condition)
29
+ other_condition.is_a?(Condition) &&
30
+ other_condition.column == column &&
31
+ other_condition.value = value &&
32
+ other_condition.method == method
33
+ end
34
+
35
+ alias_method :eql?, :==
36
+
37
+ def |(other)
38
+ Or.new(self, other)
39
+ end
40
+
41
+ def &(other)
42
+ And.new(self, other)
43
+ end
44
+
45
+ # Play "nicely" with expand_hash_conditions_for_aggregates
46
+ def to_sym
47
+ self
48
+ end
49
+ end
50
+
51
+ end
@@ -0,0 +1,48 @@
1
+ module MetaWhere
2
+ module JoinDependency
3
+
4
+ def self.included(base)
5
+ base.class_eval do
6
+ alias_method_chain :build, :metawhere
7
+ end
8
+ end
9
+
10
+ class BaseMismatchError < StandardError; end
11
+ class ConfigurationError < StandardError; end
12
+ class AssociationNotFoundError < StandardError; end
13
+
14
+ def build_with_metawhere(associations, parent = nil, join_class = Arel::InnerJoin)
15
+ parent ||= @joins.last
16
+ case associations
17
+ when Symbol, String
18
+ reflection = parent.reflections[associations.to_s.intern] or
19
+ raise AssociationNotFoundError, "Association named '#{ associations }' was not found; perhaps you misspelled it?"
20
+ unless association = find_join_association(reflection, parent)
21
+ @reflections << reflection
22
+ association = (@joins << build_join_association(reflection, parent).with_join_class(join_class)).last
23
+ end
24
+ association
25
+ when Array
26
+ associations.each do |association|
27
+ build(association, parent, join_class)
28
+ end
29
+ when Hash
30
+ associations.keys.sort{|a,b|a.to_s<=>b.to_s}.each do |name|
31
+ association = build(name, parent, join_class)
32
+ build(associations[name], association, join_class)
33
+ end
34
+ else
35
+ raise ConfigurationError, associations.inspect
36
+ end
37
+ end
38
+
39
+ def find_join_association(name_or_reflection, parent)
40
+ case name_or_reflection
41
+ when Symbol, String
42
+ join_associations.detect {|j| (j.reflection.name == name_or_reflection.to_s.intern) && (j.parent == parent)}
43
+ else
44
+ join_associations.detect {|j| (j.reflection == name_or_reflection) && (j.parent == parent)}
45
+ end
46
+ end
47
+ end
48
+ end
@@ -0,0 +1,270 @@
1
+ module MetaWhere
2
+ module Relation
3
+
4
+ def self.included(base)
5
+ base.class_eval do
6
+ alias_method_chain :reset, :metawhere
7
+ alias_method_chain :scope_for_create, :metawhere
8
+ end
9
+ end
10
+
11
+ def merge(r, association_name = nil)
12
+ if (r && (association_name || klass.name != r.klass.name)) # Merging relations with different base.
13
+ association_name ||= (default_association = reflect_on_all_associations.detect {|a| a.klass.name == r.klass.name}) ?
14
+ default_association.name : r.table_name.to_sym
15
+ r = r.clone
16
+ r.where_values.map! {|w| w.respond_to?(:to_predicate) ? {association_name => w} : w}
17
+ r.joins_values.map! {|j| [Symbol, Hash].include?(j.class) ? {association_name => j} : j}
18
+ self.joins_values += [association_name]
19
+ end
20
+ super(r)
21
+ end
22
+
23
+ alias_method :&, :merge
24
+
25
+ def reset_with_metawhere
26
+ @mw_unique_joins = @mw_association_joins = @mw_non_association_joins =
27
+ @mw_stashed_association_joins = @mw_custom_joins = nil
28
+ reset_without_metawhere
29
+ end
30
+
31
+ def scope_for_create_with_metawhere
32
+ @scope_for_create ||= begin
33
+ @create_with_value || predicate_wheres.inject({}) do |hash, where|
34
+ if is_equality_predicate?(where)
35
+ hash[where.operand1.name] = where.operand2.respond_to?(:value) ? where.operand2.value : where.operand2
36
+ end
37
+
38
+ hash
39
+ end
40
+ end
41
+ end
42
+
43
+ def build_where(opts, other = [])
44
+ if opts.is_a?(String)
45
+ @klass.send(:sanitize_sql, other.empty? ? opts : ([opts] + other))
46
+ else
47
+ predicates = []
48
+ [opts, *other].each do |arg|
49
+ predicates += Array.wrap(
50
+ case arg
51
+ when Array
52
+ @klass.send(:sanitize_sql, arg)
53
+ when Hash
54
+ @klass.send(:expand_hash_conditions_for_aggregates, arg)
55
+ else
56
+ arg
57
+ end
58
+ )
59
+ end
60
+ predicates
61
+ end
62
+ end
63
+
64
+ def build_custom_joins(joins = [], arel = nil)
65
+ arel ||= table
66
+ joins.each do |join|
67
+ next if join.blank?
68
+
69
+ @implicit_readonly = true
70
+
71
+ case join
72
+ when ActiveRecord::Associations::ClassMethods::JoinDependency::JoinAssociation
73
+ arel = arel.join(join.relation, Arel::OuterJoin).on(*join.on)
74
+ when Hash, Array, Symbol
75
+ if array_of_strings?(join)
76
+ join_string = join.join(' ')
77
+ arel = arel.join(join_string)
78
+ end
79
+ else
80
+ arel = arel.join(join)
81
+ end
82
+ end
83
+
84
+ arel
85
+ end
86
+
87
+ def custom_join_sql(*joins)
88
+ arel = table
89
+ joins.each do |join|
90
+ next if join.blank?
91
+
92
+ @implicit_readonly = true
93
+
94
+ case join
95
+ when Hash, Array, Symbol
96
+ if array_of_strings?(join)
97
+ join_string = join.join(' ')
98
+ arel = arel.join(join_string)
99
+ end
100
+ else
101
+ arel = arel.join(join)
102
+ end
103
+ end
104
+ arel.joins(arel)
105
+ end unless defined?(:custom_join_sql)
106
+
107
+ def predicate_wheres
108
+ remove_conflicting_equality_predicates(flatten_predicates(@where_values, metawhere_builder))
109
+ end
110
+
111
+ # Very occasionally, we need to get a builder for another relation, so it makes sense to factor
112
+ # this out into a public method despite only being two lines long.
113
+ def metawhere_builder
114
+ join_dependency = ActiveRecord::Associations::ClassMethods::JoinDependency.new(@klass, association_joins, custom_joins)
115
+ MetaWhere::Builder.new(join_dependency)
116
+ end
117
+
118
+ # Simulate the logic that occurs in ActiveRecord::Relation.to_a
119
+ #
120
+ # @records = eager_loading? ? find_with_associations : @klass.find_by_sql(arel.to_sql)
121
+ #
122
+ # This will let us get a dump of the SQL that will be run against the DB for debug
123
+ # purposes without actually running the query.
124
+ def debug_sql
125
+ if eager_loading?
126
+ including = (@eager_load_values + @includes_values).uniq
127
+ join_dependency = ActiveRecord::Associations::ClassMethods::JoinDependency.new(@klass, including, nil)
128
+ construct_relation_for_association_find(join_dependency).to_sql
129
+ else
130
+ arel.to_sql
131
+ end
132
+ end
133
+
134
+ def construct_limited_ids_condition(relation)
135
+ builder = relation.metawhere_builder
136
+
137
+ relation.order_values.map! {|o| o.respond_to?(:to_attribute) ? o.to_attribute(builder).to_sql : o}
138
+
139
+ super
140
+ end
141
+
142
+ def build_arel
143
+ arel = table
144
+
145
+ builder = metawhere_builder
146
+
147
+ arel = build_intelligent_joins(arel, builder) if @joins_values.present?
148
+
149
+ predicate_wheres = remove_conflicting_equality_predicates(flatten_predicates(@where_values, builder))
150
+
151
+ predicate_wheres.each do |where|
152
+ next if where.blank?
153
+
154
+ case where
155
+ when Arel::SqlLiteral
156
+ arel = arel.where(where)
157
+ else
158
+ sql = where.is_a?(String) ? where : where.to_sql
159
+ arel = arel.where(Arel::SqlLiteral.new("(#{sql})"))
160
+ end
161
+ end
162
+
163
+ arel = arel.having(*@having_values.uniq.select{|h| h.present?}) if @having_values.present?
164
+
165
+ arel = arel.take(@limit_value) if @limit_value.present?
166
+ arel = arel.skip(@offset_value) if @offset_value.present?
167
+
168
+ arel = arel.group(*@group_values.uniq.select{|g| g.present?}) if @group_values.present?
169
+
170
+ arel = build_order(arel, builder, @order_values) if @order_values.present?
171
+
172
+ arel = build_select(arel, @select_values.uniq)
173
+
174
+ arel = arel.from(@from_value) if @from_value.present?
175
+
176
+ case @lock_value
177
+ when TrueClass
178
+ arel = arel.lock
179
+ when String
180
+ arel = arel.lock(@lock_value)
181
+ end if @lock_value.present?
182
+
183
+ arel
184
+ end
185
+
186
+ private
187
+
188
+ def is_equality_predicate?(predicate)
189
+ predicate.respond_to?(:operator) && predicate.operator == :==
190
+ end
191
+
192
+ def build_intelligent_joins(arel, builder)
193
+ joined_associations = []
194
+
195
+ builder.join_dependency.graft(*stashed_association_joins)
196
+
197
+ @implicit_readonly = true unless association_joins.empty? && stashed_association_joins.empty?
198
+
199
+ to_join = []
200
+
201
+ builder.join_dependency.join_associations.each do |association|
202
+ if (association_relation = association.relation).is_a?(Array)
203
+ to_join << [association_relation.first, association.join_class, association.association_join.first]
204
+ to_join << [association_relation.last, association.join_class, association.association_join.last]
205
+ else
206
+ to_join << [association_relation, association.join_class, association.association_join]
207
+ end
208
+ end
209
+
210
+ to_join.each do |tj|
211
+ unless joined_associations.detect {|ja| ja[0] == tj[0] && ja[1] == tj[1] && ja[2] == tj[2] }
212
+ joined_associations << tj
213
+ arel = arel.join(tj[0], tj[1]).on(*tj[2])
214
+ end
215
+ end
216
+
217
+ arel = arel.join(custom_joins)
218
+ end
219
+
220
+ def build_order(arel, builder, orders)
221
+ order_attributes = orders.map {|o|
222
+ o.respond_to?(:to_attribute) ? o.to_attribute(builder, builder.join_dependency.join_base) : o
223
+ }.flatten.uniq.select {|o| o.present?}
224
+ order_attributes.map! {|a| Arel::SqlLiteral.new(a.is_a?(String) ? a : a.to_sql)}
225
+ order_attributes.present? ? arel.order(*order_attributes) : arel
226
+ end
227
+
228
+ def remove_conflicting_equality_predicates(predicates)
229
+ predicates.reverse.inject([]) { |ary, w|
230
+ unless is_equality_predicate?(w) && ary.any? {|p| is_equality_predicate?(p) && p.operand1.name == w.operand1.name}
231
+ ary << w
232
+ end
233
+ ary
234
+ }.reverse
235
+ end
236
+
237
+ def flatten_predicates(predicates, builder)
238
+ predicates.map {|p|
239
+ predicate = p.respond_to?(:to_predicate) ? p.to_predicate(builder) : p
240
+ if predicate.is_a?(Arel::Predicates::All)
241
+ flatten_predicates(predicate.predicates, builder)
242
+ else
243
+ predicate
244
+ end
245
+ }.flatten.uniq
246
+ end
247
+
248
+ def unique_joins
249
+ @mw_unique_joins ||= @joins_values.map {|j| j.respond_to?(:strip) ? j.strip : j}.uniq
250
+ end
251
+
252
+ def association_joins
253
+ @mw_association_joins ||= unique_joins.select{|j|
254
+ [Hash, Array, Symbol].include?(j.class) && !array_of_strings?(j)
255
+ }
256
+ end
257
+
258
+ def stashed_association_joins
259
+ @mw_stashed_association_joins ||= unique_joins.select {|j| j.is_a?(ActiveRecord::Associations::ClassMethods::JoinDependency::JoinAssociation)}
260
+ end
261
+
262
+ def non_association_joins
263
+ @mw_non_association_joins ||= (unique_joins - association_joins - stashed_association_joins).reject {|j| j.blank?}
264
+ end
265
+
266
+ def custom_joins
267
+ @mw_custom_joins ||= custom_join_sql(*non_association_joins)
268
+ end
269
+ end
270
+ end
@@ -0,0 +1,27 @@
1
+ module MetaWhere
2
+ module Utility
3
+ private
4
+
5
+ def args_for_predicate(method, value)
6
+ value = [Array, ActiveRecord::Associations::AssociationCollection, ActiveRecord::Relation].include?(value.class) ? value.to_a : value
7
+ if method =~ /_(any|all)$/ && value.is_a?(Array)
8
+ value
9
+ else
10
+ [value]
11
+ end
12
+ end
13
+
14
+ def method_from_value(value)
15
+ case value
16
+ when Array, Range, ActiveRecord::Associations::AssociationCollection, ActiveRecord::Relation
17
+ :in
18
+ else
19
+ :eq
20
+ end
21
+ end
22
+
23
+ def valid_comparison_method?(method)
24
+ Arel::Attribute::PREDICATES.map(&:to_s).include?(method.to_s)
25
+ end
26
+ end
27
+ end
data/lib/meta_where.rb ADDED
@@ -0,0 +1,27 @@
1
+ module MetaWhere
2
+ METHOD_ALIASES = {
3
+ 'ne' => :not_eq,
4
+ 'like' => :matches,
5
+ 'nlike' => :not_matches,
6
+ 'lte' => :lteq,
7
+ 'gte' => :gteq,
8
+ 'nin' => :not_in
9
+ }
10
+
11
+ def self.operator_overload!
12
+ require 'core_ext/symbol_operators'
13
+ end
14
+ end
15
+ require 'arel'
16
+ require 'active_record'
17
+ require 'active_support'
18
+ require 'meta_where/column'
19
+ require 'meta_where/condition'
20
+ require 'meta_where/compound'
21
+ require 'core_ext/symbol'
22
+ require 'core_ext/hash'
23
+ require 'meta_where/builder'
24
+ require 'meta_where/relation'
25
+ require 'meta_where/join_dependency'
26
+ ActiveRecord::Relation.send(:include, MetaWhere::Relation)
27
+ ActiveRecord::Associations::ClassMethods::JoinDependency.send(:include, MetaWhere::JoinDependency)
@@ -0,0 +1,105 @@
1
+ # Generated by jeweler
2
+ # DO NOT EDIT THIS FILE DIRECTLY
3
+ # Instead, edit Jeweler::Tasks in Rakefile, and run the gemspec command
4
+ # -*- encoding: utf-8 -*-
5
+
6
+ Gem::Specification.new do |s|
7
+ s.name = %q{meta_where}
8
+ s.version = "0.9.0"
9
+
10
+ s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
+ s.authors = ["Ernie Miller"]
12
+ s.date = %q{2010-08-24}
13
+ s.description = %q{
14
+ MetaWhere offers the ability to call any Arel predicate methods
15
+ (with a few convenient aliases) on your Model's attributes instead
16
+ of the ones normally offered by ActiveRecord's hash parameters. It also
17
+ adds convenient syntax for order clauses, smarter mapping of nested hash
18
+ conditions, and a debug_sql method to see the real SQL your code is
19
+ generating without running it against the database. If you like the new
20
+ AR 3.0 query interface, you'll love it with MetaWhere.
21
+ }
22
+ s.email = %q{ernie@metautonomo.us}
23
+ s.extra_rdoc_files = [
24
+ "LICENSE",
25
+ "README.rdoc"
26
+ ]
27
+ s.files = [
28
+ ".document",
29
+ ".gitignore",
30
+ ".gitmodules",
31
+ "CHANGELOG",
32
+ "Gemfile",
33
+ "LICENSE",
34
+ "README.rdoc",
35
+ "Rakefile",
36
+ "VERSION",
37
+ "lib/core_ext/hash.rb",
38
+ "lib/core_ext/symbol.rb",
39
+ "lib/core_ext/symbol_operators.rb",
40
+ "lib/meta_where.rb",
41
+ "lib/meta_where/builder.rb",
42
+ "lib/meta_where/column.rb",
43
+ "lib/meta_where/compound.rb",
44
+ "lib/meta_where/condition.rb",
45
+ "lib/meta_where/join_dependency.rb",
46
+ "lib/meta_where/relation.rb",
47
+ "lib/meta_where/utility.rb",
48
+ "meta_where.gemspec",
49
+ "test/fixtures/companies.yml",
50
+ "test/fixtures/company.rb",
51
+ "test/fixtures/data_type.rb",
52
+ "test/fixtures/data_types.yml",
53
+ "test/fixtures/developer.rb",
54
+ "test/fixtures/developers.yml",
55
+ "test/fixtures/developers_projects.yml",
56
+ "test/fixtures/note.rb",
57
+ "test/fixtures/notes.yml",
58
+ "test/fixtures/people.yml",
59
+ "test/fixtures/person.rb",
60
+ "test/fixtures/project.rb",
61
+ "test/fixtures/projects.yml",
62
+ "test/fixtures/schema.rb",
63
+ "test/helper.rb",
64
+ "test/test_relations.rb"
65
+ ]
66
+ s.homepage = %q{http://metautonomo.us/projects/metawhere/}
67
+ s.rdoc_options = ["--charset=UTF-8"]
68
+ s.require_paths = ["lib"]
69
+ s.rubygems_version = %q{1.3.7}
70
+ s.summary = %q{Add a dash of Arel awesomeness to your condition hashes.}
71
+ s.test_files = [
72
+ "test/fixtures/company.rb",
73
+ "test/fixtures/data_type.rb",
74
+ "test/fixtures/developer.rb",
75
+ "test/fixtures/note.rb",
76
+ "test/fixtures/person.rb",
77
+ "test/fixtures/project.rb",
78
+ "test/fixtures/schema.rb",
79
+ "test/helper.rb",
80
+ "test/test_relations.rb"
81
+ ]
82
+
83
+ if s.respond_to? :specification_version then
84
+ current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
85
+ s.specification_version = 3
86
+
87
+ if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
88
+ s.add_development_dependency(%q<shoulda>, [">= 0"])
89
+ s.add_runtime_dependency(%q<activerecord>, ["~> 3.0.0.rc2"])
90
+ s.add_runtime_dependency(%q<activesupport>, ["~> 3.0.0.rc2"])
91
+ s.add_runtime_dependency(%q<arel>, ["~> 1.0.0.rc1"])
92
+ else
93
+ s.add_dependency(%q<shoulda>, [">= 0"])
94
+ s.add_dependency(%q<activerecord>, ["~> 3.0.0.rc2"])
95
+ s.add_dependency(%q<activesupport>, ["~> 3.0.0.rc2"])
96
+ s.add_dependency(%q<arel>, ["~> 1.0.0.rc1"])
97
+ end
98
+ else
99
+ s.add_dependency(%q<shoulda>, [">= 0"])
100
+ s.add_dependency(%q<activerecord>, ["~> 3.0.0.rc2"])
101
+ s.add_dependency(%q<activesupport>, ["~> 3.0.0.rc2"])
102
+ s.add_dependency(%q<arel>, ["~> 1.0.0.rc1"])
103
+ end
104
+ end
105
+
@@ -0,0 +1,17 @@
1
+ initech:
2
+ name : Initech
3
+ id : 1
4
+ created_at: 1999-02-19 08:00
5
+ updated_at: 1999-02-19 08:00
6
+
7
+ aos:
8
+ name: Advanced Optical Solutions
9
+ id : 2
10
+ created_at: 2004-02-01 08:00
11
+ updated_at: 2004-02-01 08:00
12
+
13
+ mission_data:
14
+ name: Mission Data
15
+ id : 3
16
+ created_at: 1996-09-21 08:00
17
+ updated_at: 1996-09-21 08:00
@@ -0,0 +1,7 @@
1
+ class Company < ActiveRecord::Base
2
+ has_many :developers
3
+ has_many :developer_notes, :through => :developers, :source => :notes
4
+ has_many :slackers, :class_name => "Developer", :conditions => {:slacker => true}
5
+ has_many :notes, :as => :notable
6
+ has_many :data_types
7
+ end
@@ -0,0 +1,3 @@
1
+ class DataType < ActiveRecord::Base
2
+ belongs_to :company
3
+ end
@@ -0,0 +1,15 @@
1
+ <% 1.upto(9) do |n| %>
2
+ dt_<%= n %>:
3
+ company_id: <%= n % 3 + 1 %>
4
+ str : This string has <%= n %> exclamation points<%= '!' * n %>
5
+ txt : <%= 'This is some text that may or may not repeat based on the value of n.' * n %>
6
+ int : <%= n ** 3 %>
7
+ flt : <%= n.to_f / 2.0 %>
8
+ dec : <%= n.to_f ** (n + 0.1) %>
9
+ dtm : <%= (Time.utc(2009, 12, 24) + 86400 * n).to_s(:db) %>
10
+ tms : <%= (Time.utc(2009, 12, 24) + 86400 * n).to_s(:db) %>
11
+ tim : <%= Time.utc(2000, 01, 01, n+8, n).to_s(:db) %>
12
+ dat : <%= (Date.new(2009, 12, 24) + n).strftime("%Y-%m-%d") %>
13
+ bin : <%= "BLOB#{n}" * n %>
14
+ bln : <%= n % 2 > 0 ? true : false %>
15
+ <% end %>
@@ -0,0 +1,5 @@
1
+ class Developer < ActiveRecord::Base
2
+ belongs_to :company
3
+ has_and_belongs_to_many :projects
4
+ has_many :notes, :as => :notable
5
+ end
@@ -0,0 +1,55 @@
1
+ peter:
2
+ id : 1
3
+ company_id: 1
4
+ name : Peter Gibbons
5
+ salary : 100000
6
+ slacker : true
7
+
8
+ michael:
9
+ id : 2
10
+ company_id: 1
11
+ name : Michael Bolton
12
+ salary : 70000
13
+ slacker : false
14
+
15
+ samir:
16
+ id : 3
17
+ company_id: 1
18
+ name : Samir Nagheenanajar
19
+ salary : 65000
20
+ slacker : false
21
+
22
+ herb:
23
+ id : 4
24
+ company_id: 2
25
+ name : Herb Myers
26
+ salary : 50000
27
+ slacker : false
28
+
29
+ dude:
30
+ id : 5
31
+ company_id: 2
32
+ name : Some Dude
33
+ salary : 84000
34
+ slacker : true
35
+
36
+ ernie:
37
+ id : 6
38
+ company_id: 3
39
+ name : Ernie Miller
40
+ salary : 45000
41
+ slacker : true
42
+
43
+ someone:
44
+ id : 7
45
+ company_id: 3
46
+ name : Someone Else
47
+ salary : 70000
48
+ slacker : true
49
+
50
+ another:
51
+ id : 8
52
+ company_id: 3
53
+ name : Another Guy
54
+ salary : 80000
55
+ slacker : false
@@ -0,0 +1,25 @@
1
+ <% 1.upto(3) do |d| %>
2
+ y2k_<%= d %>:
3
+ developer_id: <%= d %>
4
+ project_id : 1
5
+ <% end %>
6
+
7
+ virus:
8
+ developer_id: 2
9
+ project_id : 2
10
+
11
+ <% 1.upto(8) do |d| %>
12
+ awesome_<%= d %>:
13
+ developer_id: <%= d %>
14
+ project_id : 3
15
+ <% end %>
16
+
17
+ metasearch:
18
+ developer_id: 6
19
+ project_id : 4
20
+
21
+ <% 4.upto(8) do |d| %>
22
+ another_<%= d %>:
23
+ developer_id: <%= d %>
24
+ project_id : 5
25
+ <% end %>