Class: Item::ArticleRetriever
- Inherits:
-
BaseService
- Object
- BaseService
- Item::ArticleRetriever
- Defined in:
- app/services/item/article_retriever.rb
Overview
Retrieves all the articles associated with a particular item.
Defined Under Namespace
Classes: Result
Constant Summary collapse
- ARTICLE_TYPE_TO_STI =
{ 'faq' => 'ArticleFaq', 'technical' => 'ArticleTechnical', 'training' => 'ArticleTraining', 'procedure' => 'ArticleProcedure', 'blog_post' => 'Post' }.freeze
Instance Attribute Summary collapse
-
#add_vote_data ⇒ Object
readonly
Returns the value of attribute add_vote_data.
-
#sales ⇒ Object
readonly
Returns the value of attribute sales.
-
#sti_types ⇒ Object
readonly
Returns the value of attribute sti_types.
-
#support ⇒ Object
readonly
Returns the value of attribute support.
Instance Method Summary collapse
-
#initialize(article_types:, sales: nil, support: nil, add_vote_data: false) ⇒ ArticleRetriever
constructor
==== Initialization options.
-
#process(item: nil, product_line: nil, product_category: nil, tags: nil) ⇒ Object
Retrieves all product specifications available to a given item.
Methods inherited from BaseService
#log_debug, #log_error, #log_info, #log_warning, #logger, #options, #tagged_logger
Constructor Details
#initialize(article_types:, sales: nil, support: nil, add_vote_data: false) ⇒ ArticleRetriever
==== Initialization options
- +:article_types+ - required, filter by STI type. Accepts old enum names (:faq, :technical, etc.)
- +:sales+ - true/false or nil for any
- +:support+ - true/false or nil for any
- +:add_vote_data+ - true/false. If true, custom columns vote_count and positive_votes will be added
26 27 28 29 30 31 32 33 |
# File 'app/services/item/article_retriever.rb', line 26 def initialize(article_types:, sales: nil, support: nil, add_vote_data: false) raise "Invalid article types, must be a non-empty array." unless article_types.present? && article_types.is_a?(Array) @sti_types = article_types.map { |at| ARTICLE_TYPE_TO_STI[at.to_s] || at.to_s }.compact @sales = sales @support = support @add_vote_data = add_vote_data end |
Instance Attribute Details
#add_vote_data ⇒ Object (readonly)
Returns the value of attribute add_vote_data.
17 18 19 |
# File 'app/services/item/article_retriever.rb', line 17 def add_vote_data @add_vote_data end |
#sales ⇒ Object (readonly)
Returns the value of attribute sales.
17 18 19 |
# File 'app/services/item/article_retriever.rb', line 17 def sales @sales end |
#sti_types ⇒ Object (readonly)
Returns the value of attribute sti_types.
17 18 19 |
# File 'app/services/item/article_retriever.rb', line 17 def sti_types @sti_types end |
#support ⇒ Object (readonly)
Returns the value of attribute support.
17 18 19 |
# File 'app/services/item/article_retriever.rb', line 17 def support @support end |
Instance Method Details
#process(item: nil, product_line: nil, product_category: nil, tags: nil) ⇒ Object
Retrieves all product specifications available to a given item
==== Parameters
- +item+ - The item for which you want to retrieve articles
==== Returns
A Result object with
- +articles+ - an array of articles
46 47 48 49 50 51 52 53 54 55 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 97 98 99 100 101 |
# File 'app/services/item/article_retriever.rb', line 46 def process(item: nil, product_line: nil, product_category: nil, tags: nil) articles = [] article_scope = Article.all article_scope = article_scope.where(type: sti_types) if sti_types.present? article_scope = article_scope.where(sales: sales) unless sales.nil? article_scope = article_scope.where(support: support) unless support.nil? article_scope = article_scope.with_votes if add_vote_data # `tagged_with` called on the Article base class generates taggable_type = 'Article', # but taggings are stored using the actual STI class name (e.g. 'ArticleFaq', 'Post'). # Build a correlated EXISTS subquery with the correct taggable_type(s) explicitly. if .present? tag_names = Array().flatten.filter_map(&:presence).map { |t| t.to_s.strip.downcase }.uniq taggable_types = sti_types.present? ? sti_types : [Article.base_class.name] tag_subquery = Tagging .where(Tagging[:taggable_id].eq(Article.arel_table[:id])) .where(taggable_type: taggable_types) .joins(:tag) .where(Tag[:name].lower.in(tag_names)) .select('1') article_scope = article_scope.where("EXISTS (#{tag_subquery.to_sql})") end # Preload tags for efficient rendering with filter badges # Use preload (not includes) to avoid GROUP BY conflicts with with_votes scope article_scope = article_scope.preload(taggings: :tag) # Retrieve articles tagged to this specific item if item article_scope = article_scope.for_item_sku(item.sku) articles = article_scope.to_a if item.primary_product_line pl_articles = process(product_line: item.primary_product_line, product_category: item.product_category).articles articles += pl_articles # since we added product line articles, we have to resort now using both item and product line in our array end elsif product_line article_scope = article_scope.for_product_line_url_without_order(product_line.slug_ltree.to_s) # A product category can only be applied if a product line is specified if product_category # Look for articles tagged for this product category OR with no product category specified article_scope = article_scope.where(Article[:applies_to_product_category_ids].overlap([product_category.id].compact).or(Article[:applies_to_product_category_ids].eq('{}'))) elsif (pc_ids = product_line.product_category_ids.compact).present? # .compact ensures no nil values which would cause PG::NullValueNotAllowed error with PostgreSQL's && operator article_scope = article_scope.where(Article[:applies_to_product_category_ids].overlap(pc_ids).or(Article[:applies_to_product_category_ids].eq('{}'))) end articles = article_scope.to_a else articles = article_scope.to_a end if add_vote_data articles = articles.sort_by{|a| [-(a.positive_votes.to_i + a.sort_booster.to_i), -(a.vote_count.to_i + a.sort_booster.to_i), a.subject] }.uniq else articles = articles.sort_by(&:subject) end Result.new(articles: articles) end |