Commit 7eb7d4bf799ffde3f9e370f961701a2f1e3471e3
Committed by
Rodrigo Souto
1 parent
a3c2ad9b
Exists in
master
and in
28 other branches
solr_plugin: Convert scopes to solr filters
Showing
7 changed files
with
141 additions
and
9 deletions
Show diff stats
app/controllers/application_controller.rb
... | ... | @@ -174,8 +174,6 @@ class ApplicationController < ActionController::Base |
174 | 174 | end |
175 | 175 | |
176 | 176 | def find_by_contents(asset, scope, query, paginate_options={:page => 1}, options={}) |
177 | - scope = scope.send(options[:filter]) if options[:filter] | |
178 | - | |
179 | 177 | @plugins.dispatch_first(:find_by_contents, asset, scope, query, paginate_options, options) || |
180 | 178 | fallback_find_by_contents(asset, scope, query, paginate_options, options) |
181 | 179 | end | ... | ... |
app/controllers/public/search_controller.rb
... | ... | @@ -214,6 +214,13 @@ class SearchController < PublicController |
214 | 214 | @searches[@asset] = find_by_contents(@asset, @scope, @query, paginate_options, {:category => @category, :filter => @filter}) |
215 | 215 | end |
216 | 216 | |
217 | + def find_by_contents asset, scope, query, paginate_options={:page => 1}, options={} | |
218 | + # only apply fitlers to empty query, sorting is engine specific | |
219 | + scope = scope.send(options[:filter]) if options[:filter] and @empty_query | |
220 | + | |
221 | + super asset, scope, query, paginate_options, options | |
222 | + end | |
223 | + | |
217 | 224 | private |
218 | 225 | |
219 | 226 | def visible_profiles(klass, *extra_relations) | ... | ... |
plugins/solr/lib/ext/article.rb
... | ... | @@ -24,7 +24,8 @@ class Article |
24 | 24 | {:slug => :text}, {:body => :text}, |
25 | 25 | {:abstract => :text}, {:filename => :text}, |
26 | 26 | # filtered fields |
27 | - {:solr_plugin_public => :boolean}, {:environment_id => :integer}, | |
27 | + {:solr_plugin_public => :boolean}, {:published => :boolean}, | |
28 | + {:environment_id => :integer}, | |
28 | 29 | {:profile_id => :integer}, :language, |
29 | 30 | {:solr_plugin_category_filter => :integer}, |
30 | 31 | # ordered/query-boosted fields | ... | ... |
plugins/solr/lib/ext/profile.rb
... | ... | @@ -28,7 +28,7 @@ class Profile |
28 | 28 | {:solr_plugin_category_filter => :integer}, |
29 | 29 | # ordered/query-boosted fields |
30 | 30 | {:solr_plugin_name_sortable => :string}, {:user_id => :integer}, |
31 | - :enabled, :active, :validated, :public_profile, | |
31 | + :enabled, :active, :validated, :public_profile, :visible, | |
32 | 32 | {:lat => :float}, {:lng => :float}, |
33 | 33 | :updated_at, :created_at, |
34 | 34 | ], | ... | ... |
plugins/solr/lib/solr_plugin.rb
... | ... | @@ -18,16 +18,69 @@ class SolrPlugin < Noosfero::Plugin |
18 | 18 | true |
19 | 19 | end |
20 | 20 | |
21 | + def solr_search? empty_query, klass | |
22 | + not empty_query or klass == Product | |
23 | + end | |
24 | + | |
21 | 25 | def find_by_contents(asset, scope, query, paginate_options={}, options={}) |
22 | 26 | klass = asset_class(asset) |
23 | - category = options.delete(:category) | |
24 | - filter = options.delete(:filter) | |
27 | + category = options[:category] | |
28 | + empty_query = empty_query? query, category | |
25 | 29 | |
26 | - return if empty_query?(query, category) && klass != Product | |
30 | + return unless solr_search? empty_query, klass | |
27 | 31 | |
28 | 32 | solr_options = solr_options(class_asset(klass), category) |
29 | - solr_options.merge!(products_options(user)) if klass == Product && empty_query?(query, category) | |
30 | - klass.find_by_contents(query, paginate_options, solr_options.merge(options)) | |
33 | + solr_options[:filter_queries] ||= [] | |
34 | + solr_options[:filter_queries] += scopes_to_solr_filters scope, klass, options | |
35 | + solr_options.merge! products_options(user) if klass == Product and empty_query | |
36 | + solr_options.merge! options.except(:category, :filter) | |
37 | + | |
38 | + scope.find_by_contents query, paginate_options, solr_options | |
39 | + end | |
40 | + | |
41 | + protected | |
42 | + | |
43 | + def scopes_to_solr_filters scope, klass = nil, options = {} | |
44 | + filter_queries = [] | |
45 | + klass ||= scope.base_class | |
46 | + solr_fields = klass.configuration[:solr_fields].keys | |
47 | + scopes_applied = scope.scopes_applied.dup rescue [] #rescue association and class direct filtering | |
48 | + | |
49 | + scope.current_scoped_methods[:create].each do |attr, value| | |
50 | + next unless solr_fields.include? attr.to_sym | |
51 | + | |
52 | + # if the filter is present here, then prefer it | |
53 | + scopes_applied.reject!{ |name| name == attr.to_sym } | |
54 | + | |
55 | + filter_queries << "#{attr}:#{value}" | |
56 | + end | |
57 | + | |
58 | + scopes_applied.each do |name| | |
59 | + next if name.to_s == options[:filter].to_s | |
60 | + | |
61 | + has_value = name === Hash | |
62 | + if has_value | |
63 | + name, args = name.keys.first, name.values.first | |
64 | + value = args.first | |
65 | + end | |
66 | + | |
67 | + related_field = nil | |
68 | + related_field = name if solr_fields.include? name | |
69 | + related_field = "solr_plugin_#{name}" if solr_fields.include? :"solr_plugin_#{name}" | |
70 | + | |
71 | + if has_value | |
72 | + if related_field | |
73 | + filter_queries << "#{related_field}:#{value}" | |
74 | + else | |
75 | + filter_queries << klass.send("solr_filter_#{name}", *args) | |
76 | + end | |
77 | + else | |
78 | + raise "Undeclared solr field for scope #{name}" if related_field.nil? | |
79 | + filter_queries << "#{related_field}:true" | |
80 | + end | |
81 | + end | |
82 | + | |
83 | + filter_queries | |
31 | 84 | end |
32 | 85 | |
33 | 86 | def method_missing method, *args, &block | ... | ... |
... | ... | @@ -0,0 +1,16 @@ |
1 | +require "#{File.dirname(__FILE__)}/../../test_helper" | |
2 | + | |
3 | +class SolrPlugin::PluginTest < ActiveSupport::TestCase | |
4 | + | |
5 | + def setup | |
6 | + @plugin = SolrPlugin.new | |
7 | + end | |
8 | + attr_reader :plugin | |
9 | + | |
10 | + should 'convert scopes to solr filters' do | |
11 | + person = create_user('test').person | |
12 | + result = plugin.send :scopes_to_solr_filters, person.files.public.published | |
13 | + assert_equal result, ["profile_id:#{person.id}", "published:'true'", "solr_plugin_public:true"] | |
14 | + end | |
15 | + | |
16 | +end | ... | ... |
vendor/plugins/monkey_patches/named_scope_with_applied_names/init.rb
0 → 100644
... | ... | @@ -0,0 +1,57 @@ |
1 | +require_dependency 'active_record/named_scope' | |
2 | + | |
3 | +if Rails::VERSION::STRING < "2.3.99" | |
4 | + | |
5 | + module ::ActiveRecord | |
6 | + | |
7 | + module NamedScope | |
8 | + | |
9 | + module ClassMethods | |
10 | + | |
11 | + def named_scope_with_applied_names name, options = {}, &block | |
12 | + named_scope_without_applied_names name, options, &block | |
13 | + | |
14 | + name = name.to_sym | |
15 | + scopes[name] = lambda do |parent_scope, *args| | |
16 | + scope = Scope.new(parent_scope, case options | |
17 | + when Hash | |
18 | + options | |
19 | + when Proc | |
20 | + if self.model_name != parent_scope.model_name | |
21 | + options.bind(parent_scope).call(*args) | |
22 | + else | |
23 | + options.call(*args) | |
24 | + end | |
25 | + end, &block) | |
26 | + scope.scope_name = name | |
27 | + scope | |
28 | + end | |
29 | + end | |
30 | + alias_method_chain :named_scope, :applied_names | |
31 | + end | |
32 | + | |
33 | + class Scope | |
34 | + attr_accessor :scope_name, :scopes_applied | |
35 | + | |
36 | + def initialize_with_applied_names proxy_scope, options, &block | |
37 | + initialize_without_applied_names proxy_scope, options, &block | |
38 | + self.scopes_applied ||= [] | |
39 | + self.scopes_applied += proxy_scope.send :scopes_applied if Scope === proxy_scope | |
40 | + | |
41 | + # unrelated bugfix: use if instead of unless | |
42 | + if (Scope === proxy_scope || ActiveRecord::Associations::AssociationCollection === proxy_scope) | |
43 | + @current_scoped_methods_when_defined = proxy_scope.send(:current_scoped_methods) | |
44 | + end | |
45 | + end | |
46 | + alias_method_chain :initialize, :applied_names | |
47 | + | |
48 | + def scope_name= name | |
49 | + @scope_name = name | |
50 | + self.scopes_applied << @scope_name | |
51 | + end | |
52 | + | |
53 | + end | |
54 | + | |
55 | + end | |
56 | + end | |
57 | +end | ... | ... |