Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Moves Menu query logic to component ruby #2441

Draft
wants to merge 6 commits into
base: main
Choose a base branch
from
Draft

Conversation

rosschapman
Copy link
Contributor

No description provided.

Copy link
Member

@anaulin anaulin left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If you separate this PR into two, we can merge the addition of Bullet right away. It feels like the scopes need more discussion.

@@ -44,6 +44,8 @@ class Product < Record
scope :with_menu_tag, -> { joins(:tags).merge(Tag.menu_tag) }
scope :without_menu_tag, -> { where.not(id: with_menu_tag) }
scope :sort_alpha, -> { order(name: :asc) }
scope :menu_tag_product, -> { with_all_rich_text.merge(unarchived).merge(sort_alpha) }
scope :menu_product, -> { with_all_rich_text.merge(unarchived).merge(without_menu_tag).merge(sort_alpha) }
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A few things about these two new scopes raise questions for me:

  • why are you mergeing scopes from the same model? i don't think you need nor want to do that; you can just do {... unarchived.without_menu_tag.sort_alpha ...}
  • do we want to encode eager-loading as part of a scope? we don't typically do that, because it makes the scope only suitable for that one particular use case, and bloated for other purposes; in this example, if you wanted to count the menu_products, this scope would be unnecessarily eager-loading all rich text in order to do that count
  • these are scopes on a Product model, so adding product to the scope names seems redundant (i.e. Product.menu is a better scope name than Product.menu_product)
  • it seems like the menu_tag_product scope is defined as a superset of the menu_product, which doesn't seem right

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

do we want to encode eager-loading as part of a scope

I think this makes sense to do now that I've moved the scope to methods on the component

@@ -5,6 +5,8 @@ class Tag < Record
belongs_to :marketplace, inverse_of: :tags
has_many :product_tags, inverse_of: :tag, dependent: :destroy
has_many :products, through: :product_tags, inverse_of: :tags
has_many :menu_tag_products, -> { menu_tag_product }, through: :product_tags, source: :product, inverse_of: :tags
has_many :menu_products, -> { menu_product }, through: :product_tags, source: :product, inverse_of: :tags
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I see the menu_tag_products relationship used in this PR, but not menu_products.

I definitely do not want to use a relationship that uses a scope that includes eager-loading, that doesn't seem right to me.

@rosschapman rosschapman changed the title Adds Bullet gem and adds new Product scopes and associations on Tag Moves Menu query logic to component ruby Jun 6, 2024
Copy link
Contributor Author

@rosschapman rosschapman Jun 6, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@anaulin Here's another stab where these queries (scope combos) live on the component since they are very specific to the menu interface. Notionally it feels like heavy lifting for a "view" component, but it might feel similarly awkward if we hoisted this logic to the Marketplace controller. Maybe something like a Marketplace::Menus would be a domain object model to move toward to encapsulate this responsibility. Then the concept of tag and menu are disassociated from the model's public interface.

psuedo-code:

class Marketplace
	class Menus
		has_many menus, through: tag|product_tag, -> (order: asc) 
		has_many products, through: marketplace
		scope all_products, ...
	 	
		def menus_ordered
		end

		def products_for_menu(menu)
		end
	end
end

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I like this a lot. If these scope combinations are only used in this component, putting them in the component seems great; it makes the ERB for the component cleaner without cluttering the model scopes.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants