Permalink
Browse files

Make our builders more instance based vs class based.

  • Loading branch information...
metaskills committed Dec 5, 2011
1 parent 913a61b commit ab0c89fbd5efb83d49cba29c40e47d8e4a951e1c
View
92 TODO
@@ -1,99 +1,13 @@
* Rails 3.1 Implementation
- /Users/kencollins/Repositories/rails/activerecord/lib/active_record/reflection.rb - [24, 159, 331]
- /Users/kencollins/Repositories/rails/activerecord/lib/active_record/associations.rb - [154, 1171]
- /Users/kencollins/Repositories/rails/activerecord/lib/active_record/associations/builder/association.rb - []
- /Users/kencollins/Repositories/rails/activerecord/lib/active_record/associations/builder/collection_association.rb - []
- /Users/kencollins/Repositories/rails/activerecord/lib/active_record/associations/builder/has_many.rb -
- /Users/kencollins/Repositories/rails/activerecord/lib/active_record/associations/has_many_association.rb -
- /Users/kencollins/Repositories/rails/activerecord/lib/active_record/associations/collection_association.rb - [370]
- /Users/kencollins/Repositories/rails/activerecord/lib/active_record/associations/association.rb - [97]
- /Users/kencollins/Repositories/rails/activerecord/lib/active_record/associations/association_scope.rb - [48]
-
- Notes:
-
- >> User.reflections[:boxes]
- => #<ActiveRecord::Reflection::ThroughReflection:0x007faafdddd538 @macro=:has_many, @name=:boxes, @options={:through=>:columns, :readonly=>false, :order=>"columns.position, boxes.position", :extend=>[UserBoxesAssociationExtension]}, @active_record=User(14 columns), @plural_name="boxes", @collection=true>
- >> User.reflections[:boxes].source_reflection
- => #<ActiveRecord::Reflection::AssociationReflection:0x007faafdbf1d00 @macro=:has_many, @name=:boxes, @options={:order=>"position", :extend=>[]}, @active_record=Column(3 columns), @plural_name="boxes", @collection=true>
- >> User.reflections[:boxes].through_reflection
- => #<ActiveRecord::Reflection::AssociationReflection:0x007faafddf4df0 @macro=:has_many, @name=:columns, @options={:order=>"position", :extend=>[]}, @active_record=User(14 columns), @plural_name="columns", @collection=true, @class_name="Column", @klass=Column(3 columns)>
- >> User.reflections[:boxes].source_reflection_names
- => [:box, :boxes]
- >> User.reflections[:boxes].source_options
- => {:order=>"position", :extend=>[]}
- >> User.reflections[:boxes].through_options
- => {:order=>"position", :extend=>[]}
- >> User.reflections[:boxes].class_name
- => "Box"
-
-
- >> User.reflections[:columns].primary_key_column
- => #<ActiveRecord::ConnectionAdapters::PostgreSQLColumn:0x007fdcd859b868 @name="id", @sql_type="integer", @null=false, @limit=nil, @precision=nil, @scale=nil, @type=:integer, @default=nil, @primary=true, @coder=nil>
- >> User.reflections[:columns].association_foreign_key
- => "column_id"
- >> User.reflections[:columns].association_primary_key
- => "id"
- >> User.reflections[:columns].active_record_primary_key
- => "id"
- >> User.reflections[:columns].active_record
- => User(14 columns)
-
-
- equalities = wheres.grep(Arel::Nodes::Equality)
-
- >> ActiveRecord::Associations::AssociationScope.new(User.first.association(:columns)).scope.where_values
- User Load (0.5ms) SELECT "users".* FROM "users" LIMIT 1
- => [#<Arel::Nodes::Equality:0x007ffa41eb9c70 @left=#<struct Arel::Attributes::Attribute relation=#<Arel::Table:0x007ffa41eb9f40 @name="columns", @engine=ActiveRecord::Base, @columns=nil, @aliases=[], @table_alias=nil, @primary_key=nil>, name="user_id">, @right=8>]
-
- >> ActiveRecord::Associations::AssociationScope.new(User.first.association(:columns)).send(:construct_tables)
- User Load (0.4ms) SELECT "users".* FROM "users" LIMIT 1
- => [#<Arel::Table:0x007ffa41fccbf8 @name="columns", @engine=ActiveRecord::Base, @columns=nil, @aliases=[], @table_alias=nil, @primary_key=nil>]
-
- >> ActiveRecord::Associations::AssociationScope.new(User.first.association(:columns))
- User Load (0.4ms) SELECT "users".* FROM "users" LIMIT 1
- Column Load (0.7ms) SELECT "columns".* FROM "columns" WHERE "columns"."user_id" = 8 ORDER BY position
- => #<ActiveRecord::Associations::AssociationScope:0x007ffa458fe9d0 @association=#<ActiveRecord::Associations::HasManyAssociation:0x007ffa458fea70 @target=[], @reflection=#<ActiveRecord::Reflection::AssociationReflection:0x007ffa46855820 @macro=:has_many, @name=:columns, @options={:order=>"position", :extend=>[]}, @active_record=User(14 columns), @plural_name="columns", @collection=true, @class_name="Column", @klass=Column(3 columns), @foreign_key="user_id", @active_record_primary_key="id", @type=nil, @table_name="columns", @association_foreign_key="column_id">, @owner=#<User id: 8, email: "mark.imbriaco@pobox.com", verified: true, security_token: "1b8ed73c7e8600a82bd8824d2a5b243063665b9a", token_expiry: "2010-02-07 20:44:20", created_at: "2006-12-07 17:39:27", updated_at: "2011-09-24 16:28:41", logged_in_at: "2010-02-07 00:45:11", deleted: false, delete_after: nil, uuid: "b8281ad06871012903870016cba2a0b6", iphone_verified: false, tab_links: false, password_digest: "52eb36143a4c782e202a62d5b7d64f7ce4e6ec11">, @updated=false, @loaded=false, @association_scope=nil, @proxy=[#<Column id: 3635, user_id: 8, position: 1>, #<Column id: 10, user_id: 8, position: 2>], @stale_state=nil>, @alias_tracker=#<ActiveRecord::Associations::AliasTracker:0x007ffa458fe9a8 @aliases={}, @table_joins=[]>>
-
- >> User.first.columns.unscoped { Column.where(:position => 99) }
- User Load (0.4ms) SELECT "users".* FROM "users" LIMIT 1
- Column Load (0.9ms) SELECT "columns".* FROM "columns" WHERE "columns"."position" = 99
- => []
-
- >> User.first.columns.unscoped { Column.where(:user_id => [1,2,3]) }
- User Load (0.4ms) SELECT "users".* FROM "users" LIMIT 1
- Column Load (0.9ms) SELECT "columns".* FROM "columns" WHERE "columns"."user_id" IN (1, 2, 3)
- => [#<Column id: 1, user_id: 1, position: 5>, #<Column id: 2, user_id: 1, position: 1>, #<Column id: 8, user_id: 1, position: 6>, #<Column id: 9, user_id: 1, position: 4>, #<Column id: 809, user_id: 1, position: 2>, #<Column id: 3395, user_id: 1, position: 3>]
-
- >> User.reflections[:columns].association_class
- => ActiveRecord::Associations::HasManyAssociation
-
- >> User.reflections[:columns].association_foreign_key
- => "column_id"
-
- >> User.reflect_on_all_associations(:has_many).detect { |a| a.name == :columns }
- => #<ActiveRecord::Reflection::AssociationReflection:0x007ffa46855820 @macro=:has_many, @name=:columns, @options={:order=>"position", :extend=>[]}, @active_record=User(14 columns), @plural_name="columns", @collection=true, @class_name="Column", @klass=Column(3 columns), @foreign_key="user_id", @active_record_primary_key="id", @type=nil, @table_name="columns", @association_foreign_key="column_id">
+ * Kill &block stuff.
- >> User.reflections[:columns]
- => #<ActiveRecord::Reflection::AssociationReflection:0x007ffa46855820 @macro=:has_many, @name=:columns, @options={:order=>"position", :extend=>[]}, @active_record=User(14 columns), @plural_name="columns", @collection=true, @class_name="Column", @klass=Column(3 columns), @foreign_key="user_id", @active_record_primary_key="id", @type=nil>
+ * Make association conditions use pure SQL. Avoid 100s of IDs.
- >> User.reflect_on_association(:columns)
- => #<ActiveRecord::Reflection::AssociationReflection:0x007ffa46855820 @macro=:has_many, @name=:columns, @options={:order=>"position", :extend=>[]}, @active_record=User(14 columns), @plural_name="columns", @collection=true, @class_name="Column", @klass=Column(3 columns), @foreign_key="user_id", @active_record_primary_key="id", @type=nil>
-
- >> User.first.association(:columns)
- => #<ActiveRecord::Associations::HasManyAssociation:0x007ffa464a7480 @target=[], @reflection=#<ActiveRecord::Reflection::AssociationReflection:0x007ffa46855820 @macro=:has_many, @name=:columns, @options={:order=>"position", :extend=>[]}, @active_record=User(14 columns), @plural_name="columns", @collection=true, @class_name="Column", @klass=Column(3 columns), @foreign_key="user_id", @active_record_primary_key="id", @type=nil>, @owner=#<User id: 8, email: "mark.imbriaco@pobox.com", verified: true, security_token: "1b8ed73c7e8600a82bd8824d2a5b243063665b9a", token_expiry: "2010-02-07 20:44:20", created_at: "2006-12-07 17:39:27", updated_at: "2011-09-24 16:28:41", logged_in_at: "2010-02-07 00:45:11", deleted: false, delete_after: nil, uuid: "b8281ad06871012903870016cba2a0b6", iphone_verified: false, tab_links: false, password_digest: "52eb36143a4c782e202a62d5b7d64f7ce4e6ec11">, @updated=false, @loaded=false, @association_scope=nil, @proxy=[#<Column id: 3635, user_id: 8, position: 1>, #<Column id: 10, user_id: 8, position: 2>], @stale_state=nil>
-
-
+ * Try out altering the #association_scope wheres after the fact vs a monkey patched version.
* Use appraisal for rails dep testing.
https://github.com/thoughtbot/appraisal
-* Redo for rails 3.1 tests.
-
-* Kill &block stuff.
-
-* Make association conditions use pure SQL. Avoid 100's of IDs.
-
-
View
@@ -4,6 +4,7 @@
require 'grouped_scope/arish/reflection'
require 'grouped_scope/arish/associations/collection_association'
+require 'grouped_scope/arish/associations/builder/grouped_association'
require 'grouped_scope/arish/associations/builder/grouped_collection_association'
require 'grouped_scope/arish/associations/association_scope'
require 'grouped_scope/arish/relation/predicate_builer'
@@ -0,0 +1,50 @@
+module GroupedScope
+ module Arish
+ module Associations
+ module Builder
+ class GroupedAssociation
+
+ attr_reader :model, :ungrouped_name, :ungrouped_reflection, :grouped_name, :grouped_options
+
+ def self.build(model, *association_names)
+ association_names.each { |ungrouped_name| new(model, ungrouped_name).build }
+ end
+
+ def initialize(model, ungrouped_name)
+ @model = model
+ @ungrouped_name = ungrouped_name
+ @ungrouped_reflection = find_ungrouped_reflection
+ @grouped_name = :"grouped_scope_#{ungrouped_name}"
+ @grouped_options = copy_ungrouped_reflection_options
+ end
+
+ def build
+ model.send(ungrouped_reflection.macro, grouped_name, grouped_options).tap do |grouped_reflection|
+ grouped_reflection.grouped_scope = true
+ model.grouped_reflections = model.grouped_reflections.merge(ungrouped_name => grouped_reflection)
+ define_grouped_scope_reader(model)
+ end
+ end
+
+
+ private
+
+ def define_grouped_scope_reader(model)
+ model.send(:define_method, :group) do
+ @group ||= GroupedScope::SelfGroupping.new(self)
+ end
+ end
+
+ def find_ungrouped_reflection
+ model.reflections[ungrouped_name]
+ end
+
+ def copy_ungrouped_reflection_options
+ ungrouped_reflection.options.dup
+ end
+
+ end
+ end
+ end
+ end
+end
@@ -2,48 +2,27 @@ module GroupedScope
module Arish
module Associations
module Builder
- class GroupedCollectionAssociation
+ class GroupedCollectionAssociation < GroupedAssociation
- class << self
-
- def build(model, *association_names)
- association_names.each do |name|
- ungrouped_reflection = find_ungrouped_reflection(model, name)
- options = ungrouped_reflection_options(ungrouped_reflection)
- grouped_reflection = model.send ungrouped_reflection.macro, :"grouped_scope_#{name}", options
- grouped_reflection.grouped_scope = true
- model.grouped_reflections = model.grouped_reflections.merge(name => grouped_reflection)
- end
- define_grouped_scope_reader(model)
- end
-
- private
-
- def define_grouped_scope_reader(model)
- model.send(:define_method, :group) do
- @group ||= GroupedScope::SelfGroupping.new(self)
- end
- end
-
- def find_ungrouped_reflection(model, name)
- reflection = model.reflections[name.to_sym]
- if reflection.blank? || [:has_many, :has_and_belongs_to_many].exclude?(reflection.macro)
- msg = "Cannot create a group scope for #{name.inspect}. Either the reflection is blank or not supported. " +
- "Make sure to call grouped_scope after the association you are trying to extend has been defined."
- raise ArgumentError, msg
- end
- reflection
+ private
+
+ def find_ungrouped_reflection
+ reflection = model.reflections[ungrouped_name]
+ if reflection.blank? || [:has_many, :has_and_belongs_to_many].exclude?(reflection.macro)
+ msg = "Cannot create a group scope for #{ungrouped_name.inspect}. Either the reflection is blank or not supported. " +
+ "Make sure to call grouped_scope after the association you are trying to extend has been defined."
+ raise ArgumentError, msg
end
-
- def ungrouped_reflection_options(ungrouped_reflection)
- ungrouped_reflection.options.dup.tap do |options|
- options[:class_name] = ungrouped_reflection.class_name
- if ungrouped_reflection.source_reflection && options[:source].blank?
- options[:source] = ungrouped_reflection.source_reflection.name
- end
+ reflection
+ end
+
+ def copy_ungrouped_reflection_options
+ ungrouped_reflection.options.dup.tap do |options|
+ options[:class_name] = ungrouped_reflection.class_name
+ if ungrouped_reflection.source_reflection && options[:source].blank?
+ options[:source] = ungrouped_reflection.source_reflection.name
end
end
-
end
end

0 comments on commit ab0c89f

Please sign in to comment.