spree_mobility 1.0.0 → 1.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 022505f406f3f9336ed07f01f2e991a46d04d21fb8c6a8320dc4b3c79093b227
4
- data.tar.gz: 4bd438df89aad4b7be914cf0e8e40b128b67ac70409d99bc5a775d0841d95a0a
3
+ metadata.gz: 30f3cdb07e980914cb9e50dc2ac6f2ece8ab75547b12f811e772bfacb06a0942
4
+ data.tar.gz: 2d4091a9e0399685cdfbab7f3df2c7067f567a32d133eb94f41d473caf9efbf4
5
5
  SHA512:
6
- metadata.gz: db5144c00d20a57c15a5ce19de8b507d8cf56195ca5c1de4dcb554fb21f4127713fefbb4ed3e2817aa3be5b2335916c7b544e7d363929d5042e9c37622bf2313
7
- data.tar.gz: 0cd224a84e281656efd79977715d2c688fa068ff846cea76b84f9a9506e77fb6adc1b09bc6ecf86d6e0ca51e92bbb5ce466a4c0e162745de2816e355b67dc9b2
6
+ metadata.gz: ddd330d66753f527b3f705a0957389f3f8b2cda6f410acfd3faa9e120a45583c98969f352fee5a4b9e44972c10bf6d42ff31ef03a5b42973330beeb0f3832913
7
+ data.tar.gz: cabd47580f96da77e9dc017f421a2b56f47f70e8e46f074569b3900afeb961a77118cbaa68d3ab0f11416e3e0ae6c3a96f035fc7e39441053712308bc7f77bc8
data/.gitignore CHANGED
@@ -20,3 +20,4 @@ public/spree
20
20
  .ruby-gemset
21
21
  .bundle
22
22
  gemfiles/*.gemfile.lock
23
+ /*.gem
data/README.md CHANGED
@@ -4,22 +4,7 @@ This is a Spree model translation gem based on `spree_globalize` for [Spree Comm
4
4
  It uses `mobility` instead of `globalize`, since `globalize` is not actively developed anymore.
5
5
  It is a drop-in replacement for `spree_globalize` and will use your existing translations.
6
6
 
7
- ## Improvements
8
-
9
- This gem offers several improvements over `spree_globalize`:
10
-
11
- * Proper translation fallbacks support (if a translation for the current locale is missing, it will fallback to other locales, strictly based on configured fallbacks):
12
- * for finders (slug/permalink)
13
- * when searching by product name (frontend & admin search)
14
- * Proper validations on translation models (e.g. slug presence validation), also meaning uniqueness validations will now work correctly per-locale
15
- * Better support for future versions of Rails as `mobility` is more actively maintained
16
-
17
- Admin:
18
-
19
- * Rich-text editor for product description translations in admin (if enabled)
20
- * Searching by product SKU in admin
21
- * Admin product search will no longer return duplicate results
22
- * Works correctly if using custom Spree.admin_path config
7
+ Currently, this gem is tested with Spree 4.3.1.
23
8
 
24
9
  ## Installation
25
10
 
@@ -38,16 +23,9 @@ your app spree manifest file.
38
23
 
39
24
  rails g spree_mobility:install
40
25
 
41
- This will insert these lines into your spree manifest files:
42
-
43
- ```
44
- vendor/assets/javascripts/spree/backend/all.js
45
- //= require spree/backend/spree_mobility
46
- ```
47
-
48
26
  It is also recommended to configure Mobility fallback locales, especially if your admin locale is not the same as your Store's default_locale. For example if you have en and de locale:
49
27
 
50
- ```
28
+ ```ruby
51
29
  # config/initializers/mobility.rb
52
30
  Mobility.configure do
53
31
  plugins do
@@ -58,6 +36,24 @@ end
58
36
 
59
37
  ---
60
38
 
39
+ ## Improvements over spree_globalize
40
+
41
+ This gem offers several improvements over `spree_globalize`:
42
+
43
+ * Proper translation fallbacks support (if a translation for the current locale is missing, it will fallback to other locales, strictly based on configured fallbacks):
44
+ * for finders (slug/permalink)
45
+ * when searching by product name (frontend & admin search)
46
+ * Proper validations on translation models (e.g. slug presence validation), also meaning uniqueness validations will now work correctly per-locale
47
+ * Better support for future versions of Rails as `mobility` is more actively maintained
48
+
49
+ Admin:
50
+
51
+ * Rich-text editor for product description translations in admin (if enabled)
52
+ * Admin product search will no longer return duplicate results
53
+ * Works correctly if using custom Spree.admin_path config
54
+
55
+ For more localization features, see my `better_spree_localization` gem.
56
+
61
57
  ## Model Translations
62
58
 
63
59
  This feature uses the [Mobility][3] gem to localize model data.
@@ -1,8 +1,6 @@
1
1
  require 'mobility'
2
2
  require 'mobility/backends/active_record/table'
3
3
 
4
- Dir[Rails.root.join('lib', 'spree_mobility', 'core_ext', '**', '*.rb')].each { |f| require f }
5
-
6
4
  # Extend library classes
7
5
  SpreeMobility.prepend_once(::Mobility::Backends::ActiveRecord::Table.singleton_class,
8
6
  SpreeMobility::CoreExt::Mobility::Backends::ActiveRecord::Table::MobilityActsAsParanoidDecorator)
@@ -10,9 +10,9 @@ Rails.application.config.to_prepare do
10
10
 
11
11
  module SpreeMobilityAdminStoreSearch
12
12
  def load_stores_by_query
13
- @stores =
14
- stores_scope.joins(:translations).where("LOWER(#{Spree::Store::Translation.table_name}.name) LIKE LOWER(:query)",
15
- query: "%#{params[:q]}%")
13
+ @stores =
14
+ stores_scope.joins(:translations).where("LOWER(#{Spree::Store::Translation.table_name}.name) LIKE ?",
15
+ "%#{params[:q]&.downcase}%")
16
16
  end
17
17
  end
18
18
  Spree::Admin::StoresController.prepend SpreeMobilityAdminStoreSearch
@@ -28,4 +28,4 @@ Rails.application.config.to_prepare do
28
28
  end
29
29
  end
30
30
  Spree::Api::V1::TaxonsController.prepend SpreeMobilityApiV1TaxonSearch
31
- end
31
+ end
@@ -2,10 +2,15 @@ module SpreeMobility::CoreExt::Spree::OptionTypeDecorator
2
2
  def self.prepended(base)
3
3
  base.include SpreeMobility::Translatable
4
4
  SpreeMobility.translates_for base, :name, :presentation
5
-
5
+
6
6
  base.translation_class.class_eval do
7
7
  validates :name, presence: true, uniqueness: { scope: :locale, case_sensitive: false, allow_blank: true }
8
8
  validates :presentation, presence: true
9
9
  end
10
10
  end
11
+
12
+ # Needed for admin
13
+ def json_api_columns
14
+ super + ['name', 'presentation']
15
+ end
11
16
  end
@@ -9,17 +9,17 @@ module SpreeMobility::CoreExt::Spree::OptionValueDecorator
9
9
  where(option_type_id: translated_model.option_type_id).
10
10
  joins(:translations).
11
11
  where(spree_option_value_translations: { locale: locale }).
12
- where('LOWER(spree_option_value_translations.name) = LOWER(?)', name)
12
+ where('LOWER(spree_option_value_translations.name) = ?', name.downcase)
13
13
  if check_scope.exists?
14
14
  errors.add(:name, :taken, value: name)
15
15
  end
16
16
  end
17
17
  end
18
-
18
+
19
19
  def self.prepended(base)
20
20
  base.include SpreeMobility::Translatable
21
21
  SpreeMobility.translates_for base, :name, :presentation
22
-
22
+
23
23
  base.translation_class.class_eval do
24
24
  include TranslationMethods
25
25
  validate :name_uniqueness_validation
@@ -4,18 +4,7 @@ module SpreeMobility::CoreExt::Spree
4
4
 
5
5
  module ClassMethods
6
6
  def search_by_name(query)
7
- helper = SpreeMobility::TranslationQuery.new(all.model.mobility_backend_class(:name))
8
-
9
- helper.add_joins(self.all).
10
- where("LOWER(#{helper.col_name(:name)}) LIKE LOWER(:query)", query: "%#{query}%").distinct
11
- end
12
-
13
- def search_by_name_or_sku(query)
14
- helper = SpreeMobility::TranslationQuery.new(all.model.mobility_backend_class(:name))
15
-
16
- helper.add_joins(self.all).
17
- joins(:variants_including_master).
18
- where("(LOWER(#{helper.col_name(:name)}) LIKE LOWER(:query)) OR (LOWER(#{::Spree::Variant.table_name}.sku) LIKE LOWER(:query))", query: "%#{query}%").distinct
7
+ like_any([:name], [query]).distinct
19
8
  end
20
9
 
21
10
  def like_any(fields, values)
@@ -24,12 +13,18 @@ module SpreeMobility::CoreExt::Spree
24
13
 
25
14
  helper = SpreeMobility::TranslationQuery.new(all.model.mobility_backend_class(:name))
26
15
  conditions = mobility_fields.product(values).map do |(field, value)|
27
- sanitize_sql_array(["LOWER(#{helper.col_name(field)}) LIKE LOWER(?)", "%#{value}%"])
16
+ sanitize_sql_array(["LOWER(#{helper.col_name(field)}) LIKE ?", "%#{value&.downcase}%"])
17
+ end
18
+
19
+ # From original like_any method
20
+ conditions += other_fields.product(values).map do |(field, value)|
21
+ arel_table[field].matches("%#{value}%").to_sql
28
22
  end
29
23
 
30
- scope = other_fields.empty? ? self.all : super(other_fields, values)
24
+ # Allow further adding/modification of conditions
25
+ conditions = yield(conditions) if block_given?
31
26
 
32
- helper.add_joins(scope).where(conditions.join(' OR '))
27
+ helper.add_joins(self.all).where(conditions.join(' OR '))
33
28
  end
34
29
  end
35
30
 
@@ -37,8 +32,7 @@ module SpreeMobility::CoreExt::Spree
37
32
  base.include SpreeMobility::Translatable
38
33
  SpreeMobility.translates_for base, :name, :description, :meta_title, :meta_description, :meta_keywords, :slug
39
34
  base.friendly_id :slug_candidates, use: [:history, :mobility]
40
- base.whitelisted_ransackable_scopes << 'search_by_name_or_sku'
41
-
35
+
42
36
  base.translation_class.class_eval do
43
37
  acts_as_paranoid
44
38
  after_destroy :punch_slug
@@ -1,12 +1,24 @@
1
1
  module SpreeMobility::CoreExt::Spree::Products::FindWithMobilityDecorator
2
+ private
2
3
  # The issue here is that ordering by translated attr (e.g. name) will add
3
4
  # an ORDER BY translations_table.name, but the query has a SELECT DISTINCT,
4
5
  # which would require the translations_table.name to be added to the SELECT
5
- # Instead of using DISTINCT, we select the ID only and use that as a subquery
6
- # in a simple SELECT ... FROM products WHERE products.id IN (SUBQUERY).
7
- # Performance-wise should be almost the same, or the same.
8
- def execute
9
- ::Spree::Product.where(id: super.except(:select).select(:id).distinct(false))
6
+ # So when the order is added, the appropriate SELECT should be added as well.
7
+ def ordered(products)
8
+ case sort_by
9
+ when 'name-a-z'
10
+ ordered_name(products, :asc)
11
+ when 'name-z-a'
12
+ ordered_name(products, :desc)
13
+ else
14
+ super
15
+ end
10
16
  end
11
- end
12
17
 
18
+ def ordered_name(products, direction)
19
+ helper = SpreeMobility::TranslationQuery.new(::Spree::Product.mobility_backend_class(:name))
20
+ helper.add_joins(products).
21
+ select(products.arel.projections, "#{helper.col_name(:name)} AS _name").
22
+ order(Arel.sql(helper.col_name(:name) + ((direction == :desc) ? ' DESC' : '')))
23
+ end
24
+ end
@@ -10,12 +10,12 @@ module SpreeMobility::CoreExt::Spree::TaxonDecorator
10
10
  taxonomy_id: translated_model.taxonomy_id).
11
11
  joins(:translations).
12
12
  where(spree_taxon_translations: { locale: locale }).
13
- where('LOWER(spree_taxon_translations.permalink) = LOWER(?)', permalink)
13
+ where('LOWER(spree_taxon_translations.permalink) = ?', permalink.downcase)
14
14
  if check_scope.exists?
15
15
  errors.add(:permalink, :taken, value: permalink)
16
16
  end
17
17
  end
18
-
18
+
19
19
  def name_uniqueness_validation
20
20
  return unless name.present?
21
21
  return unless translated_model
@@ -26,7 +26,7 @@ module SpreeMobility::CoreExt::Spree::TaxonDecorator
26
26
  taxonomy_id: translated_model.taxonomy_id).
27
27
  joins(:translations).
28
28
  where(spree_taxon_translations: { locale: locale }).
29
- where('LOWER(spree_taxon_translations.name) = LOWER(?)', name)
29
+ where('LOWER(spree_taxon_translations.name) = ?', name.downcase)
30
30
  if check_scope.exists?
31
31
  errors.add(:name, :taken, value: name)
32
32
  end
@@ -38,7 +38,7 @@ module SpreeMobility::CoreExt::Spree::TaxonDecorator
38
38
  SpreeMobility.translates_for base, :name, :description, :meta_title,
39
39
  :meta_description, :meta_keywords, :permalink
40
40
  base.friendly_id :permalink, slug_column: :permalink, use: [:history, :mobility]
41
-
41
+
42
42
  base.translation_class.class_eval do
43
43
  include TranslationMethods
44
44
  validates :name, presence: true
@@ -9,17 +9,17 @@ module SpreeMobility::CoreExt::Spree::TaxonomyDecorator
9
9
  where(store_id: translated_model.store_id).
10
10
  joins(:translations).
11
11
  where(spree_taxonomy_translations: { locale: locale }).
12
- where('LOWER(spree_taxonomy_translations.name) = LOWER(?)', name)
12
+ where('LOWER(spree_taxonomy_translations.name) = ?', name.downcase)
13
13
  if check_scope.exists?
14
14
  errors.add(:name, :taken, value: name)
15
15
  end
16
16
  end
17
17
  end
18
-
18
+
19
19
  def self.prepended(base)
20
20
  base.include SpreeMobility::Translatable
21
21
  SpreeMobility.translates_for base, :name
22
-
22
+
23
23
  base.translation_class.class_eval do
24
24
  include TranslationMethods
25
25
  validates :name, presence: true
@@ -8,9 +8,9 @@ module SpreeMobility::CoreExt::Spree
8
8
 
9
9
  helper.add_joins(self.joins(:product)).
10
10
  where(
11
- "(LOWER(#{helper.col_name(:name)}) LIKE LOWER(:query)) OR (LOWER(#{::Spree::Variant.table_name}.sku) LIKE LOWER(:query))", query: "%#{query}%").distinct
11
+ "(LOWER(#{helper.col_name(:name)}) LIKE :query) OR (LOWER(#{::Spree::Variant.table_name}.sku) LIKE :query)", query: "%#{query&.downcase}%").distinct
12
12
  end
13
-
13
+
14
14
  def search_by_product_name_or_sku(query)
15
15
  product_name_or_sku_cont(query)
16
16
  end
@@ -9,7 +9,7 @@ module SpreeMobility
9
9
 
10
10
  module VERSION
11
11
  MAJOR = 1
12
- MINOR = 0
12
+ MINOR = 1
13
13
  TINY = 0
14
14
  PRE = nil # 'beta'
15
15
 
@@ -14,7 +14,7 @@ Gem::Specification.new do |s|
14
14
  s.author = 'Jan Berdajs'
15
15
  s.email = 'mrbrdo@mrbrdo.net'
16
16
  s.homepage = 'https://github.com/mrbrdo'
17
- s.license = 'BSD-3'
17
+ s.license = 'BSD-3-Clause'
18
18
 
19
19
  s.files = `git ls-files`.split("\n")
20
20
  s.test_files = `git ls-files -- spec/*`.split("\n")
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: spree_mobility
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.0
4
+ version: 1.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jan Berdajs
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2022-04-22 00:00:00.000000000 Z
11
+ date: 2022-05-12 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: spree_core
@@ -204,7 +204,6 @@ files:
204
204
  - app/overrides/spree/admin/option_types/_option_value_fields/add_translation.rb
205
205
  - app/overrides/spree/admin/option_types/index/add_translation.rb
206
206
  - app/overrides/spree/admin/product_properties/_product_property_fields/add_translation.rb
207
- - app/overrides/spree/admin/products/index/search_by_name_or_sku.rb
208
207
  - app/overrides/spree/admin/promotions/index/add_translation_link.rb
209
208
  - app/overrides/spree/admin/properties/index/add_translation.rb
210
209
  - app/overrides/spree/admin/shared/_product_tabs/add_translations.rb
@@ -279,7 +278,7 @@ files:
279
278
  - spree_mobility.gemspec
280
279
  homepage: https://github.com/mrbrdo
281
280
  licenses:
282
- - BSD-3
281
+ - BSD-3-Clause
283
282
  metadata: {}
284
283
  post_install_message:
285
284
  rdoc_options: []
@@ -1,21 +0,0 @@
1
- Deface::Override.new(
2
- virtual_path: 'spree/admin/products/index',
3
- name: 'search_by_name_or_sku',
4
- replace: 'div[data-hook=admin_products_index_search] > div:first-child',
5
- text: <<-HTML
6
-
7
- <div class="col-12 col-lg-6">
8
- <div class="form-group">
9
- <%= f.label :search_by_name_or_sku, Spree.t(:name_or_sku) %>
10
- <%= f.text_field :search_by_name_or_sku, size: 15, class: "form-control js-quick-search-target js-filterable" %>
11
- </div>
12
- </div>
13
-
14
- <div class="col-12 col-lg-6">
15
- <div class="form-group">
16
- <%= f.label :search_by_name, Spree.t(:product_name) %>
17
- <%= f.text_field :search_by_name, size: 15, class: "form-control js-filterable" %>
18
- </div>
19
- </div>
20
- HTML
21
- )