diff options
| author | hukl <contact@smyck.org> | 2011-02-10 14:19:00 +0100 |
|---|---|---|
| committer | hukl <contact@smyck.org> | 2011-02-10 14:19:00 +0100 |
| commit | 7379daad1c73bd3610ed296436250b417ac3673d (patch) | |
| tree | 04f722efc678de9d3aa5bf8f1c96e3be33b18bc4 /vendor/plugins/thinking-sphinx/lib/thinking_sphinx/association.rb | |
| parent | 91633ac4419d839661e35ae8f2efe5c9089cfb67 (diff) | |
removed thinking_sphinx plugin and replaced it with gem.
also tuned dependencies
Diffstat (limited to 'vendor/plugins/thinking-sphinx/lib/thinking_sphinx/association.rb')
| -rw-r--r-- | vendor/plugins/thinking-sphinx/lib/thinking_sphinx/association.rb | 161 |
1 files changed, 0 insertions, 161 deletions
diff --git a/vendor/plugins/thinking-sphinx/lib/thinking_sphinx/association.rb b/vendor/plugins/thinking-sphinx/lib/thinking_sphinx/association.rb deleted file mode 100644 index b057035..0000000 --- a/vendor/plugins/thinking-sphinx/lib/thinking_sphinx/association.rb +++ /dev/null | |||
| @@ -1,161 +0,0 @@ | |||
| 1 | module ThinkingSphinx | ||
| 2 | # Association tracks a specific reflection and join to reference data that | ||
| 3 | # isn't in the base model. Very much an internal class for Thinking Sphinx - | ||
| 4 | # perhaps because I feel it's not as strong (or simple) as most of the rest. | ||
| 5 | # | ||
| 6 | class Association | ||
| 7 | attr_accessor :parent, :reflection, :join | ||
| 8 | |||
| 9 | # Create a new association by passing in the parent association, and the | ||
| 10 | # corresponding reflection instance. If there is no parent, pass in nil. | ||
| 11 | # | ||
| 12 | # top = Association.new nil, top_reflection | ||
| 13 | # child = Association.new top, child_reflection | ||
| 14 | # | ||
| 15 | def initialize(parent, reflection) | ||
| 16 | @parent, @reflection = parent, reflection | ||
| 17 | @children = {} | ||
| 18 | end | ||
| 19 | |||
| 20 | # Get the children associations for a given association name. The only time | ||
| 21 | # that there'll actually be more than one association is when the | ||
| 22 | # relationship is polymorphic. To keep things simple though, it will always | ||
| 23 | # be an Array that gets returned (an empty one if no matches). | ||
| 24 | # | ||
| 25 | # # where pages is an association on the class tied to the reflection. | ||
| 26 | # association.children(:pages) | ||
| 27 | # | ||
| 28 | def children(assoc) | ||
| 29 | @children[assoc] ||= Association.children(@reflection.klass, assoc, self) | ||
| 30 | end | ||
| 31 | |||
| 32 | # Get the children associations for a given class, association name and | ||
| 33 | # parent association. Much like the instance method of the same name, it | ||
| 34 | # will return an empty array if no associations have the name, and only | ||
| 35 | # have multiple association instances if the underlying relationship is | ||
| 36 | # polymorphic. | ||
| 37 | # | ||
| 38 | # Association.children(User, :pages, user_association) | ||
| 39 | # | ||
| 40 | def self.children(klass, assoc, parent=nil) | ||
| 41 | ref = klass.reflect_on_association(assoc) | ||
| 42 | |||
| 43 | return [] if ref.nil? | ||
| 44 | return [Association.new(parent, ref)] unless ref.options[:polymorphic] | ||
| 45 | |||
| 46 | # association is polymorphic - create associations for each | ||
| 47 | # non-polymorphic reflection. | ||
| 48 | polymorphic_classes(ref).collect { |klass| | ||
| 49 | Association.new parent, ::ActiveRecord::Reflection::AssociationReflection.new( | ||
| 50 | ref.macro, | ||
| 51 | "#{ref.name}_#{klass.name}".to_sym, | ||
| 52 | casted_options(klass, ref), | ||
| 53 | ref.active_record | ||
| 54 | ) | ||
| 55 | } | ||
| 56 | end | ||
| 57 | |||
| 58 | # Link up the join for this model from a base join - and set parent | ||
| 59 | # associations' joins recursively. | ||
| 60 | # | ||
| 61 | def join_to(base_join) | ||
| 62 | parent.join_to(base_join) if parent && parent.join.nil? | ||
| 63 | |||
| 64 | @join ||= ::ActiveRecord::Associations::ClassMethods::JoinDependency::JoinAssociation.new( | ||
| 65 | @reflection, base_join, parent ? parent.join : base_join.joins.first | ||
| 66 | ) | ||
| 67 | end | ||
| 68 | |||
| 69 | # Returns the association's join SQL statements - and it replaces | ||
| 70 | # ::ts_join_alias:: with the aliased table name so the generated reflection | ||
| 71 | # join conditions avoid column name collisions. | ||
| 72 | # | ||
| 73 | def to_sql | ||
| 74 | @join.association_join.gsub(/::ts_join_alias::/, | ||
| 75 | "#{@reflection.klass.connection.quote_table_name(@join.parent.aliased_table_name)}" | ||
| 76 | ) | ||
| 77 | end | ||
| 78 | |||
| 79 | # Returns true if the association - or a parent - is a has_many or | ||
| 80 | # has_and_belongs_to_many. | ||
| 81 | # | ||
| 82 | def is_many? | ||
| 83 | case @reflection.macro | ||
| 84 | when :has_many, :has_and_belongs_to_many | ||
| 85 | true | ||
| 86 | else | ||
| 87 | @parent ? @parent.is_many? : false | ||
| 88 | end | ||
| 89 | end | ||
| 90 | |||
| 91 | # Returns an array of all the associations that lead to this one - starting | ||
| 92 | # with the top level all the way to the current association object. | ||
| 93 | # | ||
| 94 | def ancestors | ||
| 95 | (parent ? parent.ancestors : []) << self | ||
| 96 | end | ||
| 97 | |||
| 98 | def has_column?(column) | ||
| 99 | @reflection.klass.column_names.include?(column.to_s) | ||
| 100 | end | ||
| 101 | |||
| 102 | def primary_key_from_reflection | ||
| 103 | if @reflection.options[:through] | ||
| 104 | @reflection.source_reflection.options[:foreign_key] || | ||
| 105 | @reflection.source_reflection.primary_key_name | ||
| 106 | else | ||
| 107 | nil | ||
| 108 | end | ||
| 109 | end | ||
| 110 | |||
| 111 | def table | ||
| 112 | if @reflection.options[:through] | ||
| 113 | @join.aliased_join_table_name | ||
| 114 | else | ||
| 115 | @join.aliased_table_name | ||
| 116 | end | ||
| 117 | end | ||
| 118 | |||
| 119 | private | ||
| 120 | |||
| 121 | # Returns all the objects that could be currently instantiated from a | ||
| 122 | # polymorphic association. This is pretty damn fast if there's an index on | ||
| 123 | # the foreign type column - but if there isn't, it can take a while if you | ||
| 124 | # have a lot of data. | ||
| 125 | # | ||
| 126 | def self.polymorphic_classes(ref) | ||
| 127 | ref.active_record.connection.select_all( | ||
| 128 | "SELECT DISTINCT #{ref.options[:foreign_type]} " + | ||
| 129 | "FROM #{ref.active_record.table_name} " + | ||
| 130 | "WHERE #{ref.options[:foreign_type]} IS NOT NULL" | ||
| 131 | ).collect { |row| | ||
| 132 | row[ref.options[:foreign_type]].constantize | ||
| 133 | } | ||
| 134 | end | ||
| 135 | |||
| 136 | # Returns a new set of options for an association that mimics an existing | ||
| 137 | # polymorphic relationship for a specific class. It adds a condition to | ||
| 138 | # filter by the appropriate object. | ||
| 139 | # | ||
| 140 | def self.casted_options(klass, ref) | ||
| 141 | options = ref.options.clone | ||
| 142 | options[:polymorphic] = nil | ||
| 143 | options[:class_name] = klass.name | ||
| 144 | options[:foreign_key] ||= "#{ref.name}_id" | ||
| 145 | |||
| 146 | quoted_foreign_type = klass.connection.quote_column_name ref.options[:foreign_type] | ||
| 147 | case options[:conditions] | ||
| 148 | when nil | ||
| 149 | options[:conditions] = "::ts_join_alias::.#{quoted_foreign_type} = '#{klass.name}'" | ||
| 150 | when Array | ||
| 151 | options[:conditions] << "::ts_join_alias::.#{quoted_foreign_type} = '#{klass.name}'" | ||
| 152 | when Hash | ||
| 153 | options[:conditions].merge!(ref.options[:foreign_type] => klass.name) | ||
| 154 | else | ||
| 155 | options[:conditions] << " AND ::ts_join_alias::.#{quoted_foreign_type} = '#{klass.name}'" | ||
| 156 | end | ||
| 157 | |||
| 158 | options | ||
| 159 | end | ||
| 160 | end | ||
| 161 | end \ No newline at end of file | ||
