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

spree 4.7 #201

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 0 additions & 8 deletions app/controllers/spree/admin/products_controller_decorator.rb

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
module SpreeRelatedProducts

Choose a reason for hiding this comment

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

Style/FrozenStringLiteralComment: Missing magic comment # frozen_string_literal: true.

module Spree
module Admin
module ProductsControllerDecorator

Choose a reason for hiding this comment

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

Style/Documentation: Missing top-level module documentation comment.

def related
load_resource
@relation_types = ::Spree::Product.relation_types
end
end
end
end
end

::Spree::Admin::ProductsController.prepend(::SpreeRelatedProducts::Spree::Admin::ProductsControllerDecorator)

Choose a reason for hiding this comment

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

Metrics/LineLength: Line is too long. [109/80]

2 changes: 2 additions & 0 deletions app/models/spree/calculator/related_product_discount.rb
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
require_dependency 'spree/calculator'

Choose a reason for hiding this comment

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

Style/FrozenStringLiteralComment: Missing magic comment # frozen_string_literal: true.


module Spree
class Calculator::RelatedProductDiscount < Spree::Calculator
def self.description
Expand Down
118 changes: 0 additions & 118 deletions app/models/spree/product_decorator.rb

This file was deleted.

119 changes: 119 additions & 0 deletions app/models/spree_related_products/spree/product_decorator.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
# frozen_string_literal: true
module SpreeRelatedProducts

Choose a reason for hiding this comment

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

Layout/EmptyLineAfterMagicComment: Add an empty line after magic comments.

module Spree
module ProductDecorator

Choose a reason for hiding this comment

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

Style/Documentation: Missing top-level module documentation comment.

def self.prepended(base)
base.has_many :relations, -> { order(:position) }, class_name: 'Spree::Relation', as: :relatable

Choose a reason for hiding this comment

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

Metrics/LineLength: Line is too long. [104/80]

base.has_many :relation_types, -> { distinct }, class_name: 'Spree::RelationType', through: :relations

Choose a reason for hiding this comment

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

Metrics/LineLength: Line is too long. [110/80]


# When a Spree::Product is destroyed, we also want to destroy all
# Spree::Relations "from" it as well as "to" it.
base.after_destroy :destroy_product_relations
base.extend ClassMethods
end

module ClassMethods

Choose a reason for hiding this comment

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

Style/Documentation: Missing top-level module documentation comment.

# Returns all the Spree::RelationType's which apply_to this class.
def relation_types
::Spree::RelationType.where(applies_to: to_s).order(:name)
end

# The AREL Relations that will be used to filter the resultant items.
#
# By default this will remove any items which are deleted,
# or not yet available.
#
# You can override this method to fine tune the filter. For example,
# to only return Spree::Product's with more than 2 items in stock, you could

Choose a reason for hiding this comment

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

Metrics/LineLength: Line is too long. [84/80]

# do the following:
#
# def self.relation_filter
# set = super
# set.where('spree_products.count_on_hand >= 2')
# end
#
# This could also feasibly be overridden to sort the result in a
# particular order, or restrict the number of items returned.
def relation_filter
where('spree_products.deleted_at' => nil)
.where('spree_products.available_on IS NOT NULL')
.where('spree_products.available_on <= ?', Time.now)
.references(self)
end
end

# Decides if there is a relevant Spree::RelationType related to this class
# which should be returned for this method.
#
# If so, it calls relations_for_relation_type. Otherwise it passes
# it up the inheritance chain.
def method_missing(method, *args)

Choose a reason for hiding this comment

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

Style/MethodMissing: When using method_missing, define respond_to_missing?.

relation_type = find_relation_type(method)
if relation_type.nil?
super
else
relations_for_relation_type(relation_type)
end
end

def has_related_products?(relation_method)

Choose a reason for hiding this comment

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

Naming/PredicateName: Rename has_related_products? to related_products?.

find_relation_type(relation_method).present?
end

def destroy_product_relations
# First we destroy relationships "from" this Product to others.
relations.destroy_all
# Next we destroy relationships "to" this Product.
::Spree::Relation.where(related_to_type: self.class.to_s).where(related_to_id: id).destroy_all

Choose a reason for hiding this comment

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

Metrics/LineLength: Line is too long. [102/80]

end

private

def find_relation_type(relation_name)
self.class.relation_types.detect do |rt|
format_name(rt.name) == format_name(relation_name)
end
rescue ActiveRecord::StatementInvalid
# This exception is throw if the relation_types table does not exist.
# And this method is getting invoked during the execution of a migration
# from another extension when both are used in a project.
nil
end

# Returns all the Products that are related to this record for the given RelationType.

Choose a reason for hiding this comment

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

Metrics/LineLength: Line is too long. [92/80]

#
# Uses the Relations to find all the related items, and then filters
# them using +Product.relation_filter+ to remove unwanted items.
def relations_for_relation_type(relation_type)
# Find all the relations that belong to us for this RelationType, ordered by position

Choose a reason for hiding this comment

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

Metrics/LineLength: Line is too long. [93/80]

related_ids = relations.where(relation_type_id: relation_type.id)
.order(:position)
.select(:related_to_id)

# Construct a query for all these records
result = self.class.where(id: related_ids)

# Merge in the relation_filter if it's available
result = result.merge(self.class.relation_filter) if relation_filter

# make sure results are in same order as related_ids array (position order)

Choose a reason for hiding this comment

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

Metrics/LineLength: Line is too long. [83/80]

result.where(id: related_ids).order(:position) if result.present?

result
end

# Simple accessor for the class-level relation_filter.
# Could feasibly be overloaded to filter results relative to this
# record (eg. only higher priced items)
def relation_filter
self.class.relation_filter
end

def format_name(name)
name.to_s.downcase.tr(' ', '_').pluralize
end
end
end
end

::Spree::Product.prepend(::SpreeRelatedProducts::Spree::ProductDecorator)
6 changes: 0 additions & 6 deletions app/overrides/add_product_relation_admin_sub_menu_tab.rb

This file was deleted.

6 changes: 0 additions & 6 deletions app/overrides/add_related_product_admin_tabs.rb

This file was deleted.

4 changes: 0 additions & 4 deletions app/views/spree/admin/products/_related_products.html.erb

This file was deleted.

13 changes: 5 additions & 8 deletions app/views/spree/admin/relation_types/edit.html.erb
Original file line number Diff line number Diff line change
@@ -1,16 +1,13 @@
<% content_for :page_title do %>
<%= Spree.t(:editing_resource, resource: Spree::RelationType.model_name.human) %>
<%= link_to Spree.t(:relation_types), spree.admin_relation_types_url %> /
<%= @relation_type.name.capitalize %>
<% end %>

<%= render partial: 'spree/admin/shared/error_messages', locals: { target: @relation_type } %>

<% content_for :page_actions do %>
<%= button_link_to Spree.t(:back_to_resource_list, resource: Spree::RelationType.model_name.human), spree.admin_relation_types_path, class: 'btn-primary', icon: 'arrow-left' %>
<% end %>
<%= render partial: 'spree/admin/shared/error_messages', locals: { target: @role } %>

<%= form_for [:admin, @relation_type] do |f| %>
<fieldset>
<%= render 'form', f: f %>
<%= render 'spree/admin/shared/edit_resource_links' %>
<%= render partial: 'form', locals: { f: f } %>
<%= render partial: 'spree/admin/shared/edit_resource_links' %>
</fieldset>
<% end %>
8 changes: 1 addition & 7 deletions app/views/spree/admin/relation_types/index.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,8 @@
<%= button_link_to Spree.t(:new_relation_type), new_object_url, class: 'btn-primary', icon: 'add', id: 'admin_new_relation_type' %>
<% end %>

<% if @relation_types.any? %>
<% if @relation_types.present? %>
<table class="table" id="listing_relation_types" data-hook>
<colgroup>
<col style="width: 20%" />
<col style="width: 20%" />
<col style="width: 40%" />
<col style="width: 20%" />
</colgroup>
<thead>
<tr data-hook="admin_relation_types_index_headers">
<th><%= Spree.t(:name) %></th>
Expand Down
18 changes: 18 additions & 0 deletions config/initializers/related_product.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
Rails.application.config.after_initialize do
if Spree::Core::Engine.backend_available?
Rails.application.config.spree_backend.tabs[:product].add(
::Spree::Admin::Tabs::TabBuilder.new(Spree.t(:related_products), ->(resource) { ::Spree::Core::Engine.routes.url_helpers.related_admin_product_path(resource) }).
with_icon_key('resize-small').
with_active_check.
with_manage_ability_check(::Spree::Relation).
build
)

Rails.application.config.spree_backend.main_menu.add_to_section('products',
::Spree::Admin::MainMenu::ItemBuilder.new('relation_types', ::Spree::Core::Engine.routes.url_helpers.admin_relation_types_path).
with_manage_ability_check(::Spree::RelationType).
with_match_path('/relation_types').
build
)
end
end
1 change: 1 addition & 0 deletions config/locales/en.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,3 +16,4 @@ en:
add_related_product: Add Related Product
name_or_sku_short: Name or SKU
no_relation_types: You need to configure Relation Types before you can use this feature.
relation_types: Relation Types
17 changes: 7 additions & 10 deletions lib/spree_related_products/engine.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,19 +4,16 @@ class Engine < Rails::Engine
isolate_namespace Spree
engine_name 'spree_related_products'

config.autoload_paths += %W(#{config.root}/lib #{config.root}/app/models/spree/calculator)
config.autoload_paths += %W(#{config.root}/lib)

initializer 'spree.promo.register.promotion.calculators' do |app|
app.config.spree.calculators.promotion_actions_create_adjustments << Spree::Calculator::RelatedProductDiscount
def self.activate
Dir.glob(File.join(File.dirname(__FILE__), '../../app/**/*_decorator*.rb')) do |c|
Rails.configuration.cache_classes ? require(c) : load(c)
end
end

class << self
def activate
cache_klasses = %W(#{config.root}/app/**/*_decorator*.rb)
Dir.glob(cache_klasses) do |klass|
Rails.configuration.cache_classes ? require(klass) : load(klass)
end
end
config.after_initialize do |app|
app.config.spree.calculators.promotion_actions_create_adjustments << ::Spree::Calculator::RelatedProductDiscount
end

config.to_prepare(&method(:activate).to_proc)
Expand Down