Class: Spree::ProductGroup
- Inherits:
-
ActiveRecord::Base
- Object
- ActiveRecord::Base
- Spree::ProductGroup
- Defined in:
- app/models/spree/product_group.rb
Class Method Summary collapse
-
.from_url(url) ⇒ Object
Testing utility: creates new ProductGroup from search permalink url.
-
.new_from_products(products, attrs = {}) ⇒ Object
Build a new product group with a scope to filter by specified products.
Instance Method Summary collapse
- #add_scope(scope_name, arguments = []) ⇒ Object
- #apply_on(scopish, use_order = true) ⇒ Object
-
#dynamic_products(use_order = true) ⇒ Object
returns chain of named scopes generated from order scope and product scopes.
- #from_product_group(opg) ⇒ Object
- #from_route(attrs) ⇒ Object
- #from_search(search_hash) ⇒ Object
- #generate_preview(size = ) ⇒ Object
- #include?(product) ⇒ Boolean
- #order_scope ⇒ Object
- #order_scope=(scope_name) ⇒ Object
-
#products(use_order = true) ⇒ Object
Does the final ordering if requested TODO: move the order stuff out of the above - is superfluous now.
- #scopes_to_hash ⇒ Object
- #to_param ⇒ Object
- #to_s ⇒ Object
- #update_memberships ⇒ Object
Class Method Details
.from_url(url) ⇒ Object
Testing utility: creates new ProductGroup from search permalink url. Follows conventions for accessing PGs from URLs, as decoded in routes
45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 |
# File 'app/models/spree/product_group.rb', line 45 def self.from_url(url) pg = nil; case url when /\/t\/(.+?)\/s\/(.+)/ then taxons = $1; attrs = $2; when /\/t\/(.+?)\/pg\/(.+)/ then taxons = $1; pg_name = $2; when /(.*?)\/s\/(.+)/ then attrs = $2; when /(.*?)\/pg\/(.+)/ then pg_name = $2; else return(nil) end if pg_name && opg = ProductGroup.find_by_permalink(pg_name) pg = new.from_product_group(opg) elsif attrs attrs = url.split('/') pg = new.from_route(attrs) end taxon = taxons && taxons.split('/').last pg.add_scope('in_taxon', taxon) if taxon pg end |
.new_from_products(products, attrs = {}) ⇒ Object
Build a new product group with a scope to filter by specified products
194 195 196 197 198 |
# File 'app/models/spree/product_group.rb', line 194 def self.new_from_products(products, attrs = {}) pg = new(attrs) pg.product_scopes.build(:name => 'with_ids', :arguments => [products.map(&:id).join(',')]) pg end |
Instance Method Details
#add_scope(scope_name, arguments = []) ⇒ Object
94 95 96 97 98 99 100 101 102 103 104 |
# File 'app/models/spree/product_group.rb', line 94 def add_scope(scope_name, arguments=[]) if scope_name.to_s !~ /eval|send|system|[^a-z0-9_!?]/ self.product_scopes << ProductScope.new({ :name => scope_name.to_s, :arguments => [*arguments] }) else raise ArgumentError.new("'#{scope_name}` can't be used as scope") end self end |
#apply_on(scopish, use_order = true) ⇒ Object
106 107 108 109 110 111 112 113 114 115 116 117 118 119 |
# File 'app/models/spree/product_group.rb', line 106 def apply_on(scopish, use_order = true) # There's bug in AR, it doesn't merge :order, instead it takes order # from first nested_scope so we have to apply ordering FIRST. # see #2253 on rails LH base_product_scope = scopish if use_order && !self.order_scope.blank? && Product.respond_to?(self.order_scope.intern) base_product_scope = base_product_scope.send(self.order_scope) end return self.product_scopes.reject { |s| s.is_ordering? }.inject(base_product_scope) do |result, scope| scope.apply_on(result) end end |
#dynamic_products(use_order = true) ⇒ Object
returns chain of named scopes generated from order scope and product scopes.
122 123 124 |
# File 'app/models/spree/product_group.rb', line 122 def dynamic_products(use_order = true) apply_on(Product.group_by_products_id, use_order) end |
#from_product_group(opg) ⇒ Object
67 68 69 70 71 72 73 74 75 |
# File 'app/models/spree/product_group.rb', line 67 def from_product_group(opg) self.product_scopes = opg.product_scopes.map{|ps| ps = ps.clone; ps.product_group_id = nil; ps.product_group = self; ps } self end |
#from_route(attrs) ⇒ Object
77 78 79 80 81 82 83 84 |
# File 'app/models/spree/product_group.rb', line 77 def from_route(attrs) self.order_scope = attrs.pop if attrs.length % 2 == 1 attrs.each_slice(2) do |scope| next unless Product.respond_to?(scope.first) add_scope(scope.first, scope.last.split(',')) end self end |
#from_search(search_hash) ⇒ Object
86 87 88 89 90 91 92 |
# File 'app/models/spree/product_group.rb', line 86 def from_search(search_hash) search_hash.each_pair do |scope_name, scope_attribute| add_scope(scope_name, scope_attribute) end self end |
#generate_preview(size = ) ⇒ Object
168 169 170 171 172 |
# File 'app/models/spree/product_group.rb', line 168 def generate_preview(size = Spree::Config[:admin_pgroup_preview_size]) count = self.class.count_by_sql ["SELECT COUNT(*) FROM spree_product_groups_products WHERE spree_product_groups_products.product_group_id = ?", self] return count, products.limit(size) end |
#include?(product) ⇒ Boolean
143 144 145 146 |
# File 'app/models/spree/product_group.rb', line 143 def include?(product) res = apply_on(Product.where(:id => product.id), false) res.count > 0 end |
#order_scope ⇒ Object
179 180 181 182 183 |
# File 'app/models/spree/product_group.rb', line 179 def order_scope if scope = product_scopes.detect {|s| s.is_ordering?} scope.name end end |
#order_scope=(scope_name) ⇒ Object
185 186 187 188 189 190 191 |
# File 'app/models/spree/product_group.rb', line 185 def order_scope=(scope_name) if scope = product_scopes.detect {|s| s.is_ordering?} scope.update_attribute(:name, scope_name) else self.product_scopes.build(:name => scope_name, :arguments => []) end end |
#products(use_order = true) ⇒ Object
Does the final ordering if requested TODO: move the order stuff out of the above - is superfluous now
128 129 130 131 132 133 134 135 136 137 138 139 140 141 |
# File 'app/models/spree/product_group.rb', line 128 def products(use_order = true) cached_group = Product.in_cached_group(self) if cached_group.limit(1).blank? dynamic_products(use_order) elsif !use_order cached_group else product_scopes.select { |s| s.is_ordering? }.inject(cached_group) { |res,order| order.apply_on(res) } end end |
#scopes_to_hash ⇒ Object
148 149 150 151 152 153 154 |
# File 'app/models/spree/product_group.rb', line 148 def scopes_to_hash result = {} self.product_scopes.each do |scope| result[scope.name] = scope.arguments end result end |
#to_param ⇒ Object
156 157 158 |
# File 'app/models/spree/product_group.rb', line 156 def to_param permalink.present? ? permalink : (permalink_was || name.to_s.to_url) end |
#to_s ⇒ Object
174 175 176 |
# File 'app/models/spree/product_group.rb', line 174 def to_s "<Spree::ProductGroup" + (id && "[#{id}]").to_s + ":'#{to_url}'>" end |
#update_memberships ⇒ Object
160 161 162 163 164 165 166 |
# File 'app/models/spree/product_group.rb', line 160 def update_memberships # wipe everything directly to avoid expensive in-rails sorting ActiveRecord::Base.connection.execute "DELETE FROM spree_product_groups_products WHERE product_group_id = #{self.id}" # and generate the new group entirely in SQL ActiveRecord::Base.connection.execute "INSERT INTO spree_product_groups_products #{dynamic_products(false).scoped(:select => "spree_products.id, #{self.id}").to_sql}" end |