Files

Class Index [+]

Quicksearch

UbiquoCategories::Extensions::ActiveRecord::ClassMethods

Constants

DEFAULT_CATEGORIZED_OPTIONS
(Not documented)

Public Instance Methods

categorize_options(field) click to toggle source

Returns the associated options for the categorized field

     # File vendor/plugins/ubiquo_categories/lib/ubiquo_categories/extensions/active_record.rb, line 186
186:         def categorize_options(field)
187:           categorized_with_options = self.categorized_with_options_lookup
188:           raise UbiquoCategories::CategorizationNotFoundError if categorized_with_options.blank?
189:           association_name = field.to_s.pluralize.to_sym
190:           categorized_with_options[association_name]
191:         end
categorized_with(field, options = {}) click to toggle source

Class method for ActiveRecord that states that a attribute is categorized

Example:

  categorized_with :city

possible options:

  :from => CategorySet key(s) where this attribute should feed from.
           If it's not provided, will pluralize the attribute name and
           use it as the key.
  :size => the max number of categories that can be selected.
           Can be an integer or :many if there is no limit. Default: 1
  :separator => The char(s) that delimite the different categories when
                creating them from a string. Defaults to double hash (##)
     # File vendor/plugins/ubiquo_categories/lib/ubiquo_categories/extensions/active_record.rb, line 34
 34:         def categorized_with(field, options = {})
 35:           options.reverse_merge!(DEFAULT_CATEGORIZED_OPTIONS)
 36: 
 37:           association_name = field.to_s.pluralize
 38: 
 39:           self.has_many(:category_relations, {
 40:               :as => :related_object,
 41:               :class_name => "::CategoryRelation",
 42:               :dependent => :destroy,
 43:               :order => "category_relations.position ASC"
 44:           }) unless self.respond_to?(:category_relations)
 45: 
 46:           # TODO: Possible Rails bug? Conditions doesn't get applied
 47:           # inside the first join (monkey patch applied), correct query below:
 48: 
 49:           # SELECT DISTINCT "articles".id FROM "articles"
 50:           # LEFT OUTER JOIN "category_relations" ON (
 51:           #   "articles"."id" = "category_relations"."related_object_id" AND
 52:           #   "category_relations"."related_object_type" = 'Article' AND
 53:           #   "category_relations"."attr_name" = 'sections') <-- association_name
 54:           # LEFT OUTER JOIN "categories" ON (
 55:           #   "categories"."id" = "category_relations"."category_id")
 56:           # ORDER BY categories.name asc LIMIT 11 OFFSET 0;
 57:           self.has_many(:"#{field}_category_relations", {
 58:               :as => :related_object,
 59:               :class_name => "::CategoryRelation",
 60:               :conditions => ["category_relations.attr_name = ?", association_name],
 61:               :dependent => :destroy,
 62:               :order => "category_relations.position ASC"
 63:           })
 64: 
 65:           association_name = field.to_s.pluralize
 66:           set_key = (options[:from] || association_name).to_s
 67: 
 68:           @categorized_with_options ||= {}
 69:           @categorized_with_options[association_name.to_sym] = options
 70: 
 71:           assign_to_set = Proc.new do |categories, object|
 72:             set = CategorySet.find_by_key(set_key) || CategorySet.find_by_key(set_key.singularize)
 73:             raise UbiquoCategories::SetNotFoundError unless set
 74: 
 75:             categories = uhook_assign_to_set set, categories, object
 76:             [set, categories]
 77:           end
 78: 
 79:           proc = Proc.new do
 80: 
 81:             define_method "<<" do |categories|
 82:               set, categories = assign_to_set.call(categories, proxy_owner)
 83: 
 84:               categories.each do |category|
 85:                 unless has_category? category.to_s
 86:                   raise UbiquoCategories::LimitError if is_full?
 87:                   @reflection.through_reflection.klass.create(
 88:                     :attr_name => association_name,
 89:                     :related_object => proxy_owner,
 90:                     :category => category
 91:                   )
 92:                 end
 93:               end
 94:               reset
 95:             end
 96: 
 97:             if options[:size] == 1
 98:               # Returns directly the instance if only one category is allowed
 99:               def method_missing(method, *args)
100:                 if load_target
101:                   if @target.first.respond_to?(method)
102:                     if block_given?
103:                       @target.first.send(method, *args)  { |*block_args| yield(*block_args) }
104:                     else
105:                       @target.first.send(method, *args)
106:                     end
107:                   else
108:                     super
109:                   end
110:                 end
111:               end
112:             end
113: 
114:             define_method 'is_full?' do
115:               return false if options[:size].to_sym == :many
116:               Array(self).size >= options[:size]
117:             end
118: 
119:             define_method 'will_be_full?' do |categories|
120:               return false if options[:size].to_sym == :many
121:               categories.size > options[:size]
122:             end
123: 
124:             define_method 'has_category?' do |category|
125:               if category.is_a? Category
126:                 Array(self).include? category
127:               else
128:                 Array(self).map(&:to_s).include? category.to_s
129:               end
130:             end
131: 
132:             # Automatically set the required attr_name when creating through the through
133:             define_method 'construct_owner_attributes' do |reflection|
134:               super.merge(:attr_name => association_name.to_s)
135:             end
136: 
137:           end
138: 
139:           self.has_many(association_name.to_sym, {
140:               :through => :"#{field}_category_relations",
141:               :class_name => "::Category",
142:               :source => :category,
143:               :conditions => ["category_relations.attr_name = ?", association_name],
144:               :order => "category_relations.position ASC",
145:             },&proc)
146: 
147:           define_method "#{association_name}_with_categories=" do |categories|
148:             categories = categories.split(options[:separator]) if categories.is_a? String
149: 
150:             set, categories = assign_to_set.call(categories, self)
151: 
152:             raise UbiquoCategories::LimitError if send(association_name).will_be_full? categories
153: 
154:             CategoryRelation.send(:with_scope, :create => {:attr_name => association_name}) do
155:               self.send("#{association_name}_without_categories=", categories)
156:             end
157: 
158:           end
159: 
160:           alias_method_chain "#{association_name}=", 'categories'
161: 
162:           named_scope "with_#{association_name}_in", lambda{ |*values|
163:             category_conditions_for field, values
164:           }
165: 
166:           if field != association_name
167:             alias_method field, association_name
168:             alias_method "#{field}=", "#{association_name}="
169:             klass = class << self; self; end
170:             klass.send :alias_method,  "with_#{field}_in", "with_#{association_name}_in"
171:           end
172: 
173:           prepare_categories_join_sql field
174: 
175:           uhook_categorized_with field, options
176: 
177:         end
categorized_with_options_lookup() click to toggle source

(Not documented)

     # File vendor/plugins/ubiquo_categories/lib/ubiquo_categories/extensions/active_record.rb, line 179
179:         def categorized_with_options_lookup
180:           return {} if self.name == ::ActiveRecord::Base.name
181:           @categorized_with_options = {} if @categorized_with_options.blank?
182:           return @categorized_with_options.reverse_merge(self.superclass.categorized_with_options_lookup)
183:         end
category_conditions_for(field, category_names) click to toggle source

(Not documented)

     # File vendor/plugins/ubiquo_categories/lib/ubiquo_categories/extensions/active_record.rb, line 193
193:         def category_conditions_for field, category_names
194:           association_name = field.to_s.pluralize.to_sym
195: 
196:           options = categorize_options(association_name)
197:           raise UbiquoCategories::CategorizationNotFoundError unless options
198: 
199:           set = CategorySet.find_by_key "#{options[:from] || association_name}"
200:           raise UbiquoCategories::SetNotFoundError unless set
201: 
202:           value = Array(category_names).map do |category_name|
203:             value = set.uhook_category_identifier_for_name category_name
204:           end.compact
205: 
206:           value = [0] if value.blank? # to prevent rails sql bad formation
207: 
208:           {
209:             :conditions => Category.uhook_category_identifier_condition(value, association_name),
210:             :readonly => false,
211:             :joins => categorize_options(field)[:join_sql]
212:           }
213:         end
method_missing(method, *args) {|*block_args| ...} click to toggle source

Returns directly the instance if only one category is allowed

     # File vendor/plugins/ubiquo_categories/lib/ubiquo_categories/extensions/active_record.rb, line 99
 99:               def method_missing(method, *args)
100:                 if load_target
101:                   if @target.first.respond_to?(method)
102:                     if block_given?
103:                       @target.first.send(method, *args)  { |*block_args| yield(*block_args) }
104:                     else
105:                       @target.first.send(method, *args)
106:                     end
107:                   else
108:                     super
109:                   end
110:                 end
111:               end

Protected Instance Methods

prepare_categories_join_sql(field) click to toggle source

(Not documented)

     # File vendor/plugins/ubiquo_categories/lib/ubiquo_categories/extensions/active_record.rb, line 217
217:         def prepare_categories_join_sql field
218:           association_name = field.to_s.pluralize.to_s
219: 
220:           relation_table = connection.quote_table_name(CategoryRelation.table_name)
221:           category_table = connection.quote_table_name(Category.table_name)
222:           relation_alias = connection.quote_table_name(CategoryRelation.alias_for_association(association_name))
223:           category_alias = connection.quote_table_name(Category.alias_for_association(association_name))
224: 
225:           categorize_options(field)[:join_sql] = "INNER JOIN \#{relation_table} \#{relation_alias} ON\n(\#{table_name}.id = \#{relation_alias}.related_object_id AND\n\#{relation_alias}.related_object_type = \#{quote_value(base_class.name)})\nINNER JOIN \#{category_table} \#{category_alias} ON\n(\#{category_alias}.id = \#{relation_alias}.category_id) AND\n\#{relation_alias}.attr_name = \#{quote_value(association_name)}\n"
226:         end

Disabled; run with $DEBUG to generate this.

[Validate]

Generated with the Darkfish Rdoc Generator 1.1.6.