Class: Spree::Channel
- Inherits:
-
Object
- Object
- Spree::Channel
- Defined in:
- app/models/spree/channel.rb
Overview
Lightweight distribution surface within a Store: online storefront, POS, marketplace integration, wholesale portal. Channels carry order attribution and the routing-strategy override.
Constant Summary collapse
- DEFAULT_CODE =
'online'.freeze
Instance Method Summary collapse
-
#add_products(product_ids, published_at: nil, unpublished_at: nil) ⇒ Integer
Publishes the given products on this channel by creating/upserting ProductPublications.
- #can_be_deleted? ⇒ Boolean
-
#remove_products(product_ids) ⇒ Integer
Unpublishes the given products from this channel.
Methods included from Metadata
#metadata, #metadata=, #public_metadata=
Instance Method Details
#add_products(product_ids, published_at: nil, unpublished_at: nil) ⇒ Integer
Publishes the given products on this channel by creating/upserting ProductPublications. Optionally sets the publication window; if not given, the products will be published immediately with no end date.
56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 |
# File 'app/models/spree/channel.rb', line 56 def add_products(product_ids, published_at: nil, unpublished_at: nil) product_ids = Array(product_ids).map(&:to_s).uniq return 0 if product_ids.empty? now = Time.current # Only include window columns in the upsert payload when the caller # explicitly passed a value. Leaving them out keeps existing # publication schedules intact on re-publish — otherwise +on_duplicate: # :update+ + +update_only+ would rewrite scheduled +published_at+ / # +unpublished_at+ to NULL whenever the bulk action re-runs without # dates. base = { channel_id: id, created_at: now, updated_at: now } base[:published_at] = published_at unless published_at.nil? base[:unpublished_at] = unpublished_at unless unpublished_at.nil? records_to_upsert = product_ids.map { |product_id| base.merge(product_id: product_id) } # Only update the window columns the caller passed. When neither was # passed, treat re-publish as a no-op (+on_duplicate: :skip+ → MySQL # +INSERT IGNORE+, PG/SQLite +ON CONFLICT DO NOTHING+). update_columns = [] update_columns << :published_at unless published_at.nil? update_columns << :unpublished_at unless unpublished_at.nil? opts = if update_columns.empty? { on_duplicate: :skip } else { record_timestamps: false, update_only: update_columns, on_duplicate: :update } end # MySQL infers the conflict target from the table's unique constraints # and rejects an explicit +unique_by+; PostgreSQL/SQLite require it. opts[:unique_by] = %i[product_id channel_id] unless mysql_adapter? Spree::ProductPublication.upsert_all(records_to_upsert, **opts) products = Spree::Product.where(id: product_ids) products.touch_all products.each(&:enqueue_search_index) touch records_to_upsert.size end |
#can_be_deleted? ⇒ Boolean
116 117 118 |
# File 'app/models/spree/channel.rb', line 116 def can_be_deleted? !default? end |
#remove_products(product_ids) ⇒ Integer
Unpublishes the given products from this channel.
101 102 103 104 105 106 107 108 109 110 111 112 113 |
# File 'app/models/spree/channel.rb', line 101 def remove_products(product_ids) product_ids = Array(product_ids).map(&:to_s).uniq return 0 if product_ids.empty? count = publications.where(product_id: product_ids).destroy_all.size products = Spree::Product.where(id: product_ids) products.touch_all products.each(&:enqueue_search_index) touch if count.positive? count end |