spree_mobility 1.0.0 → 1.1.0

Sign up to get free protection for your applications and to get access to all the features.
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
- )