diff --git a/lib/rating/models/rating/rating.rb b/lib/rating/models/rating/rating.rb index 7236a1a..c3a6b7c 100644 --- a/lib/rating/models/rating/rating.rb +++ b/lib/rating/models/rating/rating.rb @@ -29,7 +29,10 @@ module Rating (CAST(#{total_count} AS DECIMAL(17, 14)) / #{distinct_count}) count_avg, COALESCE(AVG(value), 0) rating_avg FROM #{rate_table_name} - WHERE resource_type = :resource_type #{scope_type_query(resource, scopeable)} + WHERE + resource_type = :resource_type + #{scope_type_query(resource, scopeable)} + #{scope_where_query(resource)} ).squish execute_sql [sql, values] @@ -54,7 +57,11 @@ module Rating COALESCE(SUM(value), 0) rating_sum, COUNT(1) rating_count FROM #{rate_table_name} - WHERE resource_type = ? AND resource_id = ? #{scope_type_and_id_query(resource, scopeable)} + WHERE + resource_type = ? + AND resource_id = ? + #{scope_type_and_id_query(resource, scopeable)} + #{scope_where_query(resource)} ).squish values = [sql, resource.class.base_class.name, resource.id] @@ -104,7 +111,10 @@ module Rating %(( SELECT GREATEST(#{count}, 1) FROM #{rate_table_name} - WHERE resource_type = :resource_type #{scope_type_query(resource, scopeable)} + WHERE + resource_type = :resource_type + #{scope_type_query(resource, scopeable)} + #{scope_where_query(resource)} )) end @@ -124,6 +134,16 @@ module Rating 'AND scopeable_type = ? AND scopeable_id = ?' end + + def scope_where_query(resource) + return '' if where_condition(resource).blank? + + "AND #{where_condition(resource)}" + end + + def where_condition(resource) + resource.rating_options[:where] + end end end end diff --git a/spec/factories/toy.rb b/spec/factories/toy.rb new file mode 100644 index 0000000..2c1c97e --- /dev/null +++ b/spec/factories/toy.rb @@ -0,0 +1,6 @@ +# frozen_string_literal: true + +FactoryBot.define do + factory :toy do + end +end diff --git a/spec/models/extension/where_spec.rb b/spec/models/extension/where_spec.rb new file mode 100644 index 0000000..9d1aba5 --- /dev/null +++ b/spec/models/extension/where_spec.rb @@ -0,0 +1,33 @@ +# frozen_string_literal: true + +require 'rails_helper' + +RSpec.describe Rating::Extension, 'unscoped_rating' do + let!(:author_1) { create :author } + let!(:author_2) { create :author } + let!(:author_3) { create :author } + let!(:author_4) { create :author } + let!(:author_5) { create :author } + let!(:resource) { create :toy } + + it 'uses rate with where condition' do + author_1.rate resource, 1 + author_2.rate resource, 2 + author_3.rate resource, 3 + author_4.rate resource, 4 + author_5.rate resource, 5 + + ratings = Rating::Rating.all.order('id') + + expect(ratings.size).to eq 1 + + rating = ratings[0] + + expect(rating.average.to_s).to eq '3.0' + expect(rating.estimate.to_s).to eq '3.0' + expect(rating.resource).to eq resource + expect(rating.scopeable).to eq nil + expect(rating.sum).to eq 9 + expect(rating.total).to eq 3 + end +end diff --git a/spec/support/db/migrate/create_toys_table.rb b/spec/support/db/migrate/create_toys_table.rb new file mode 100644 index 0000000..2ca3745 --- /dev/null +++ b/spec/support/db/migrate/create_toys_table.rb @@ -0,0 +1,8 @@ +# frozen_string_literal: true + +class CreateToysTable < ActiveRecord::Migration[5.0] + def change + create_table :toys do |t| + end + end +end diff --git a/spec/support/migrate.rb b/spec/support/migrate.rb index 75e2028..9d2ef6a 100644 --- a/spec/support/migrate.rb +++ b/spec/support/migrate.rb @@ -7,6 +7,7 @@ CreateRatingTable.new.change CreateArticlesTable.new.change CreateAuthorsTable.new.change +CreateToysTable.new.change CreateGlobalsTable.new.change CreateCategoriesTable.new.change diff --git a/spec/support/models/toy.rb b/spec/support/models/toy.rb new file mode 100644 index 0000000..15fb73d --- /dev/null +++ b/spec/support/models/toy.rb @@ -0,0 +1,5 @@ +# frozen_string_literal: true + +class Toy < ::ActiveRecord::Base + rating where: 'value > 1 and value < 5' +end