Update has_many_polymorphs to 421dd0bd60b246652bbbafd64724ebf1efa27607

This commit is contained in:
Eric Allen 2009-12-07 18:20:17 -05:00
parent 804d59c542
commit 144e74682b
49 changed files with 189 additions and 126 deletions

View file

@ -14,7 +14,7 @@ class ActiveRecord::Base
extend ActiveRecord::Associations::PolymorphicClassMethods
end
if ENV['HMP_DEBUG'] or ENV['RAILS_ENV'] =~ /development|test/ and ENV['USER'] == 'eweaver'
if ENV['HMP_DEBUG'] || ENV['RAILS_ENV'] =~ /development|test/ && ENV['USER'] == 'eweaver'
require 'has_many_polymorphs/debugging_tools'
end

View file

@ -88,18 +88,19 @@ module ActiveRecord #:nodoc:
def construct_quoted_owner_attributes(*args) #:nodoc:
# no access to returning() here? why not?
type_key = @reflection.options[:foreign_type_key]
{@reflection.primary_key_name => @owner.id,
type_key=> (@owner.class.base_class.name if type_key)}
h = {@reflection.primary_key_name => @owner.id}
h[type_key] = @owner.class.base_class.name if type_key
h
end
def construct_from #:nodoc:
# build the FROM part of the query, in this case, the polymorphic join table
@reflection.klass.table_name
@reflection.klass.quoted_table_name
end
def construct_owner #:nodoc:
# the table name for the owner object's class
@owner.class.table_name
@owner.class.quoted_table_name
end
def construct_owner_key #:nodoc:
@ -114,10 +115,10 @@ module ActiveRecord #:nodoc:
def construct_joins(custom_joins = nil) #:nodoc:
# build the string of default joins
"JOIN #{construct_owner} polymorphic_parent ON #{construct_from}.#{@reflection.options[:foreign_key]} = polymorphic_parent.#{construct_owner_key} " +
"JOIN #{construct_owner} AS polymorphic_parent ON #{construct_from}.#{@reflection.options[:foreign_key]} = polymorphic_parent.#{construct_owner_key} " +
@reflection.options[:from].map do |plural|
klass = plural._as_class
"LEFT JOIN #{klass.table_name} ON #{construct_from}.#{@reflection.options[:polymorphic_key]} = #{klass.table_name}.#{klass.primary_key} AND #{construct_from}.#{@reflection.options[:polymorphic_type_key]} = #{@reflection.klass.quote_value(klass.base_class.name)}"
"LEFT JOIN #{klass.quoted_table_name} ON #{construct_from}.#{@reflection.options[:polymorphic_key]} = #{klass.quoted_table_name}.#{klass.primary_key} AND #{construct_from}.#{@reflection.options[:polymorphic_type_key]} = #{@reflection.klass.quote_value(klass.base_class.name)}"
end.uniq.join(" ") + " #{custom_joins}"
end

View file

@ -1,6 +1,5 @@
require 'initializer' unless defined? ::Rails::Initializer
require 'dispatcher' unless defined? ::ActionController::Dispatcher
require 'action_controller/dispatcher' unless defined? ::ActionController::Dispatcher
module HasManyPolymorphs
@ -17,9 +16,11 @@ Note that you can override DEFAULT_OPTIONS via Rails::Configuration#has_many_pol
end
=end
MODELS_ROOT = "#{RAILS_ROOT}/app/models/"
DEFAULT_OPTIONS = {
:file_pattern => "#{RAILS_ROOT}/app/models/**/*.rb",
:file_pattern => "#{MODELS_ROOT}**/*.rb",
:file_exclusions => ['svn', 'CVS', 'bzr'],
:methods => ['has_many_polymorphs', 'acts_as_double_polymorphic_join'],
:requirements => []}
@ -27,6 +28,7 @@ Note that you can override DEFAULT_OPTIONS via Rails::Configuration#has_many_pol
mattr_accessor :options
@@options = HashWithIndifferentAccess.new(DEFAULT_OPTIONS)
# Dispatcher callback to load polymorphic relationships from the top down.
def self.autoload
@ -37,12 +39,14 @@ Note that you can override DEFAULT_OPTIONS via Rails::Configuration#has_many_pol
require requirement
end
Dir[options[:file_pattern]].each do |filename|
Dir.glob(options[:file_pattern]).each do |filename|
next if filename =~ /#{options[:file_exclusions].join("|")}/
open filename do |file|
open(filename) do |file|
if file.grep(/#{options[:methods].join("|")}/).any?
begin
model = File.basename(filename)[0..-4].camelize
modelname = filename[0..-4]
modelname.slice!(MODELS_ROOT)
model = modelname.camelize
_logger_warn "preloading parent model #{model}"
model.constantize
rescue Object => e
@ -64,7 +68,7 @@ class Rails::Initializer #:nodoc:
alias_method_chain :after_initialize, :autoload
end
Dispatcher.to_prepare(:has_many_polymorphs_autoload) do
ActionController::Dispatcher.to_prepare(:has_many_polymorphs_autoload) do
# Make sure it gets loaded in the app
HasManyPolymorphs.autoload
end

View file

@ -398,7 +398,7 @@ Be aware, however, that <tt>NULL != 'Spot'</tt> returns <tt>false</tt> due to SQ
}
if reflection.options[:foreign_type_key]
type_check = "#{reflection.options[:foreign_type_key]} = #{quote_value(self.base_class.name)}"
type_check = "#{reflection.options[:join_class_name].constantize.quoted_table_name}.#{reflection.options[:foreign_type_key]} = #{quote_value(self.base_class.name)}"
conjunction = options[:conditions] ? " AND " : nil
options[:conditions] = "#{options[:conditions]}#{conjunction}#{type_check}"
options[:as] = reflection.options[:as]

View file

@ -45,9 +45,13 @@ class Hash
# An implementation of select that returns a Hash.
def _select
Hash[*self.select do |key, value|
yield key, value
end._flatten_once]
if RUBY_VERSION >= "1.9"
Hash[*self.select {|k, v| yield k, v }.flatten]
else
Hash[*self.select do |key, value|
yield key, value
end._flatten_once]
end
end
end