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

Fix duplicate variants on product page #2630

Merged
merged 1 commit into from
Apr 3, 2018

Conversation

mamhoff
Copy link
Contributor

@mamhoff mamhoff commented Mar 15, 2018

This fixes issue #1654. The default pricing options class has a
search_arguments which adds nil as a matching possibility for the
price's country field (in order to accomodate for the fallback price).

In Spree::Variant.with_prices, Spree::Price.where(search_arguments) is
merged into a Variant query. This results in duplicate variants being
returned.

From the standard product page, Spree::Variant.with_prices is called
by Spree::Product#variants_and_option_values_for(current_pricing_options).

@jhawthorn
Copy link
Contributor

I made a similar fix to Product#with_master_price by using an EXISTS subquery (see #2021). That might work better here than using a DISTINCT

@mamhoff mamhoff force-pushed the fix-duplicate-variants branch from 4213e69 to dd4ad1b Compare March 16, 2018 11:06
@@ -138,11 +138,21 @@ def self.active(currency = nil)
end

# Returns variants that have a price for the given pricing options
# If you have modified the pricing options class, you might want to modify this scope too.

Choose a reason for hiding this comment

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

Trailing whitespace detected.

@mamhoff mamhoff force-pushed the fix-duplicate-variants branch 2 times, most recently from 8ad7711 to 23d5c76 Compare March 16, 2018 11:19
This fixes issue solidusio#1654. The default pricing options class has a
`search_arguments` which adds `nil` as a matching possibility for the
price's country field (in order to accomodate for the fallback price).

In Spree::Variant.with_prices, Spree::Price.where(search_arguments) is
merged into a Variant query. This results in duplicate variants being
returned.

From the standard product page, `Spree::Variant.with_prices` is called
by `Spree::Product#variants_and_option_values_for(current_pricing_options)`.
This replaces the 'merge' call in Spree::Variant.with_prices with an
SQL EXISTS subquery.

There are quirks with ActiveRecord here:
`.where(pricing_options.search_arguments)` - which translates to
`.where(currency: "EUR", country_iso: ["FR", nil])` and does pretty
much the same as the expression in this commit. However, that one
just simply does not work in this context, which is why I took the decision
to write the SQL by hand.
@mamhoff mamhoff force-pushed the fix-duplicate-variants branch from 23d5c76 to 409c68f Compare March 16, 2018 11:36
@mamhoff
Copy link
Contributor Author

mamhoff commented Mar 16, 2018

Thank you John, good tip! Weirdly though, in this particular context ActiveRecord seems to have difficulty generating the correct SQL for the pricing options' search arguments, so I had to write some SQL by hand to make it work. This means that if a store overrides their pricing options class they might have to override the with_prices scope, too. If anyone can come up with a more generic solution, I'm all for it.

@jhawthorn
Copy link
Contributor

I think as long as it works under both MySQL and Postgres (and it seems to), the raw SQL is fine.

@jhawthorn jhawthorn merged commit c071f8f into solidusio:master Apr 3, 2018
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.

3 participants