Class: Spree::Product
- Extended by:
- FriendlyId
- Includes:
- Scopes, SoftDeletable
- Defined in:
- app/models/spree/product.rb,
app/models/spree/product/scopes.rb
Overview
Products represent an entity for sale in a store. Products can have variations, called variants. Product properties include description, permalink, availability, shipping category, etc. that do not change by variant.
Defined Under Namespace
Modules: Scopes
Constant Summary collapse
- MASTER_ATTRIBUTES =
[ :cost_currency, :cost_price, :depth, :height, :price, :sku, :track_inventory, :weight, :width, ]
Instance Attribute Summary collapse
-
#option_values_hash ⇒ Object
Returns the value of attribute option_values_hash.
Class Method Summary collapse
-
.like_any(fields, values) ⇒ ActiveRecord::Relation
Poor man’s full text search.
Instance Method Summary collapse
-
#available? ⇒ Boolean
Determines if product is available.
-
#deleted? ⇒ Boolean
Use for checking whether this product has been deleted.
-
#discontinued? ⇒ Boolean
Determines if product is discontinued.
-
#duplicate ⇒ Spree::Product
Creates a new product with the same attributes, variants, etc.
-
#empty_option_values? ⇒ Boolean
True if there are no option values.
-
#ensure_option_types_exist_for_values_hash ⇒ Array
Ensures option_types and product_option_types exist for keys in option_values_hash.
- #find_or_build_master ⇒ Object
-
#find_variant_property_rule(option_value_ids) ⇒ Spree::VariantPropertyRule
Finds the variant property rule that matches the provided option value ids.
-
#gallery ⇒ Spree::Gallery
The gallery for the product, which represents all the images associated with it, including those on its variants.
-
#has_variants? ⇒ Boolean
True if there are any variants.
-
#possible_promotions ⇒ Array
All advertised and not-rejected promotions.
-
#property(property_name) ⇒ String
The value of the given property.
-
#set_property(property_name, property_value) ⇒ Object
Assigns the given value to the given property.
-
#tax_category ⇒ Spree::TaxCategory
Tax category for this product, or the default tax category.
-
#total_on_hand ⇒ Fixnum, Infinity
The number of on-hand stock items; Infinity if any variant does not track inventory.
-
#variant_option_values_by_option_type(variant_scope = nil) ⇒ Hash<Spree::OptionType, Array<Spree::OptionValue>>
Groups all of the option values that are associated to the product’s variants, grouped by option type.
-
#variants_and_option_values_for(pricing_options = Spree::Config.default_pricing_options) ⇒ Array<Spree::Variant>
All variants with at least one option value.
Methods included from Scopes
Methods inherited from Base
Methods included from Core::Permalinks
#generate_permalink, #save_permalink
Instance Attribute Details
#option_values_hash ⇒ Object
Returns the value of attribute option_values_hash.
127 128 129 |
# File 'app/models/spree/product.rb', line 127 def option_values_hash @option_values_hash end |
Class Method Details
.like_any(fields, values) ⇒ ActiveRecord::Relation
Poor man’s full text search.
Filters products to those which have any of the strings in values
in any of the fields in fields
.
219 220 221 222 223 224 |
# File 'app/models/spree/product.rb', line 219 def self.like_any(fields, values) conditions = fields.product(values).map do |(field, value)| arel_table[field].matches("%#{value}%") end where conditions.inject(:or) end |
Instance Method Details
#available? ⇒ Boolean
Determines if product is available. A product is available if it has not been deleted, the available_on date is in the past and the discontinue_on date is nil or in the future.
197 198 199 |
# File 'app/models/spree/product.rb', line 197 def available? !deleted? && available_on&.past? && !discontinued? end |
#deleted? ⇒ Boolean
Use for checking whether this product has been deleted. Provided for overriding the logic for determining if a product is deleted.
188 189 190 |
# File 'app/models/spree/product.rb', line 188 def deleted? !!deleted_at end |
#discontinued? ⇒ Boolean
Determines if product is discontinued.
A product is discontinued if the discontinue_on date is not nil and in the past.
207 208 209 |
# File 'app/models/spree/product.rb', line 207 def discontinued? !!discontinue_on&.past? end |
#duplicate ⇒ Spree::Product
Creates a new product with the same attributes, variants, etc.
179 180 181 182 |
# File 'app/models/spree/product.rb', line 179 def duplicate duplicator = ProductDuplicator.new(self) duplicator.duplicate end |
#empty_option_values? ⇒ Boolean
Returns true if there are no option values.
254 255 256 |
# File 'app/models/spree/product.rb', line 254 def empty_option_values? .empty? || !option_types.left_joins(:option_values).where('spree_option_values.id IS NULL').empty? end |
#ensure_option_types_exist_for_values_hash ⇒ Array
Ensures option_types and product_option_types exist for keys in option_values_hash.
170 171 172 173 174 |
# File 'app/models/spree/product.rb', line 170 def ensure_option_types_exist_for_values_hash return if option_values_hash.nil? required_option_type_ids = option_values_hash.keys.map(&:to_i) self.option_type_ids |= required_option_type_ids end |
#find_or_build_master ⇒ Object
75 76 77 |
# File 'app/models/spree/product.rb', line 75 def find_or_build_master master || build_master end |
#find_variant_property_rule(option_value_ids) ⇒ Spree::VariantPropertyRule
Finds the variant property rule that matches the provided option value ids.
301 302 303 304 305 |
# File 'app/models/spree/product.rb', line 301 def find_variant_property_rule(option_value_ids) variant_property_rules.find do |rule| rule.matches_option_value_ids?(option_value_ids) end end |
#gallery ⇒ Spree::Gallery
The gallery for the product, which represents all the images associated with it, including those on its variants
311 312 313 |
# File 'app/models/spree/product.rb', line 311 def gallery @gallery ||= Spree::Config.product_gallery_class.new(self) end |
#has_variants? ⇒ Boolean
Returns true if there are any variants.
157 158 159 |
# File 'app/models/spree/product.rb', line 157 def has_variants? variants.any? end |
#possible_promotions ⇒ Array
Returns all advertised and not-rejected promotions.
280 281 282 283 |
# File 'app/models/spree/product.rb', line 280 def possible_promotions promotion_ids = promotion_rules.map(&:promotion_id).uniq Spree::Promotion.advertised.where(id: promotion_ids).reject(&:inactive?) end |
#property(property_name) ⇒ String
Returns the value of the given property. nil if property is undefined on this product.
260 261 262 263 |
# File 'app/models/spree/product.rb', line 260 def property(property_name) return nil unless prop = properties.find_by(name: property_name) product_properties.find_by(property: prop).try(:value) end |
#set_property(property_name, property_value) ⇒ Object
Assigns the given value to the given property.
269 270 271 272 273 274 275 276 277 |
# File 'app/models/spree/product.rb', line 269 def set_property(property_name, property_value) ActiveRecord::Base.transaction do # Works around spree_i18n https://github.com/spree/spree/issues/301 property = Spree::Property.create_with(presentation: property_name).find_or_create_by(name: property_name) product_property = Spree::ProductProperty.where(product: self, property: property).first_or_initialize product_property.value = property_value product_property.save! end end |
#tax_category ⇒ Spree::TaxCategory
Returns tax category for this product, or the default tax category.
162 163 164 |
# File 'app/models/spree/product.rb', line 162 def tax_category super || Spree::TaxCategory.find_by(is_default: true) end |
#total_on_hand ⇒ Fixnum, Infinity
The number of on-hand stock items; Infinity if any variant does not track inventory.
289 290 291 292 293 294 295 |
# File 'app/models/spree/product.rb', line 289 def total_on_hand if any_variants_not_track_inventory? Float::INFINITY else stock_items.sum(:count_on_hand) end end |
#variant_option_values_by_option_type(variant_scope = nil) ⇒ Hash<Spree::OptionType, Array<Spree::OptionValue>>
Groups all of the option values that are associated to the product’s variants, grouped by option type.
used to determine the applied option_types associated with the products variants grouped by option type
242 243 244 245 246 247 248 249 250 251 |
# File 'app/models/spree/product.rb', line 242 def variant_option_values_by_option_type(variant_scope = nil) option_value_scope = Spree::OptionValuesVariant.joins(:variant) .where(spree_variants: { product_id: id }) option_value_scope = option_value_scope.merge(variant_scope) if variant_scope option_value_ids = option_value_scope.distinct.pluck(:option_value_id) Spree::OptionValue.where(id: option_value_ids). includes(:option_type). order("#{Spree::OptionType.table_name}.position, #{Spree::OptionValue.table_name}.position"). group_by(&:option_type) end |
#variants_and_option_values_for(pricing_options = Spree::Config.default_pricing_options) ⇒ Array<Spree::Variant>
Returns all variants with at least one option value.
229 230 231 232 233 |
# File 'app/models/spree/product.rb', line 229 def variants_and_option_values_for( = Spree::Config.) variants.includes(:option_values).with_prices().select do |variant| variant.option_values.any? end end |