Permalink
Browse files

Merge branch 'arel'

  • Loading branch information...
2 parents 81a965a + e111f5f commit e131cfd85139e557176777ee0316e318c233f3e2 Katsuya Noguchi committed Aug 26, 2012
View
@@ -1,3 +1,7 @@
+* Add `with_normalized_reputation` and `with_normalized_reputation_only`
+
+* Add `with_reputation` and `with_reputation_only` methods.
+
## ActiveRecordReputationSystem 1.3.4 ##
* Fix name of a migration class again.
View
@@ -15,7 +15,9 @@
##
require 'reputation_system/base'
-require 'reputation_system/query'
+require 'reputation_system/query_methods'
+require 'reputation_system/finder_methods'
+require 'reputation_system/query_builder'
require 'reputation_system/evaluation'
require 'reputation_system/network'
require 'reputation_system/reputation'
@@ -50,7 +50,9 @@ def has_reputation(reputation_name, options)
# If it is first time to be called
unless ancestors.include?(ReputationSystem::Reputation)
has_many :reputations, :as => :target, :class_name => "RSReputation", :dependent => :destroy
- include ReputationSystem::Query
+ include ReputationSystem::QueryBuilder
+ include ReputationSystem::QueryMethods
+ include ReputationSystem::FinderMethods
include ReputationSystem::Reputation
include ReputationSystem::Scope
end
@@ -0,0 +1,84 @@
+##
+# Copyright 2012 Twitter, Inc
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+##
+
+module ReputationSystem
+module FinderMethods
+ def self.included(klass)
+ klass.extend ClassMethods
+ end
+
+ module ClassMethods
+
+ def find_with_reputation(*args)
+ reputation_name, srn, find_scope, options = parse_query_args(*args)
+ options[:select] = build_select_statement(table_name, reputation_name, options[:select])
+ options[:joins] = build_join_statement(table_name, name, srn, options[:joins])
+ options[:conditions] = build_condition_statement(options[:conditions])
+ find(find_scope, options)
+ end
+
+ def count_with_reputation(*args)
+ reputation_name, srn, find_scope, options = parse_query_args(*args)
+ options[:joins] = build_join_statement(table_name, name, srn, options[:joins])
+ options[:conditions] = build_condition_statement(options[:conditions])
+ options[:conditions][0].gsub!(reputation_name.to_s, "COALESCE(rs_reputations.value, 0)")
+ count(find_scope, options)
+ end
+
+ def find_with_normalized_reputation(*args)
+ reputation_name, srn, find_scope, options = parse_query_args(*args)
+ options[:select] = build_select_statement(table_name, reputation_name, options[:select], srn, true)
+ options[:joins] = build_join_statement(table_name, name, srn, options[:joins])
+ options[:conditions] = build_condition_statement(options[:conditions])
+ find(find_scope, options)
+ end
+
+ def find_with_reputation_sql(*args)
+ reputation_name, srn, find_scope, options = parse_query_args(*args)
+ options[:select] = build_select_statement(table_name, reputation_name, options[:select])
+ options[:joins] = build_join_statement(table_name, name, srn, options[:joins])
+ options[:conditions] = build_condition_statement(options[:conditions])
+ if respond_to?(:construct_finder_sql, true)
+ construct_finder_sql(options)
+ else
+ construct_finder_arel(options).to_sql
+ end
+ end
+
+ protected
+
+ def parse_query_args(*args)
+ case args.length
+ when 2
+ find_scope = args[1]
+ options = {}
+ when 3
+ find_scope = args[1]
+ options = args[2]
+ when 4
+ scope = args[1]
+ find_scope = args[2]
+ options = args[3]
+ else
+ raise ArgumentError, "Expecting 2, 3 or 4 arguments but got #{args.length}"
+ end
+ reputation_name = args[0]
+ srn = ReputationSystem::Network.get_scoped_reputation_name(name, reputation_name, scope)
+ [reputation_name, srn, find_scope, options]
+ end
+ end
+ end
+end
@@ -1,102 +0,0 @@
-##
-# Copyright 2012 Twitter, Inc
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-##
-
-module ReputationSystem
- module Query
- def self.included(klass)
- klass.extend ClassMethods
- end
-
- module ClassMethods
- DELTA = 0.000001
-
- def find_with_reputation(*args)
- reputation_name, srn, find_scope, options = parse_query_args(*args)
- options[:select] ||= sanitize_sql_array(["%s.*", self.table_name])
- options[:select] = sanitize_sql_array(["%s, COALESCE(rs_reputations.value, 0) AS %s", options[:select], reputation_name])
- find_options = get_find_options(srn, options)
- find_options[:conditions][0].gsub!(reputation_name.to_s, "COALESCE(rs_reputations.value, 0)")
- find(find_scope, find_options)
- end
-
- def count_with_reputation(*args)
- reputation_name, srn, find_scope, options = parse_query_args(*args)
- find_options = get_find_options(srn, options)
- find_options[:conditions][0].gsub!(reputation_name.to_s, "COALESCE(rs_reputations.value, 0)")
- count(find_scope, find_options)
- end
-
- def find_with_normalized_reputation(*args)
- reputation_name, srn, find_scope, options = parse_query_args(*args)
- max = RSReputation.max(srn, self.name)
- min = RSReputation.min(srn, self.name)
- range = max - min
- options[:select] ||= sanitize_sql_array(["%s.*", self.table_name])
- if range < DELTA
- options[:select] = sanitize_sql_array(["%s, (0) AS normalized_%s", options[:select], reputation_name])
- else
- options[:select] = sanitize_sql_array(["%s, ((rs_reputations.value - %s) / %s) AS normalized_%s", options[:select], min, range, reputation_name])
- end
- find_options = get_find_options(srn, options)
- find(find_scope, options)
- end
-
- def find_with_reputation_sql(*args)
- reputation_name, srn, find_scope, options = parse_query_args(*args)
- options[:select] ||= sanitize_sql_array(["%s.*", self.table_name])
- options[:select] = sanitize_sql_array(["%s, COALESCE(rs_reputations.value, 0) AS %s", options[:select], reputation_name])
- find_options = get_find_options(srn, options)
- if respond_to?(:construct_finder_sql, true)
- construct_finder_sql(find_options)
- else
- construct_finder_arel(find_options).to_sql
- end
- end
-
- protected
- def get_find_options(srn, options)
- options[:joins] ||= []
- options[:joins] = [options[:joins]] unless options[:joins].is_a? Array
- temp_joins = sanitize_sql_array(["LEFT JOIN rs_reputations ON %s.id = rs_reputations.target_id AND rs_reputations.target_type = ? AND rs_reputations.reputation_name = ? AND rs_reputations.active = ?", self.name, srn.to_s, true])
- temp_joins = sanitize_sql_array([temp_joins, self.table_name])
- options[:joins] << temp_joins
- options[:conditions] ||= [""]
- options[:conditions] = [options[:conditions]] unless options[:conditions].is_a? Array
- options
- end
-
- def parse_query_args(*args)
- case args.length
- when 2
- find_scope = args[1]
- options = {}
- when 3
- find_scope = args[1]
- options = args[2]
- when 4
- scope = args[1]
- find_scope = args[2]
- options = args[3]
- else
- raise ArgumentError, "Expecting 2, 3 or 4 arguments but got #{args.length}"
- end
- reputation_name = args[0]
- srn = ReputationSystem::Network.get_scoped_reputation_name(name, reputation_name, scope)
- [reputation_name, srn, find_scope, options]
- end
- end
- end
-end
@@ -0,0 +1,73 @@
+##
+# Copyright 2012 Twitter, Inc
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+##
+
+module ReputationSystem
+ module QueryBuilder
+ def self.included(klass)
+ klass.extend ClassMethods
+ end
+
+ module ClassMethods
+ DELTA = 0.000001
+ REPUTATION_JOIN_STATEMENT = "LEFT JOIN rs_reputations ON %s.id = rs_reputations.target_id AND rs_reputations.target_type = ? AND rs_reputations.reputation_name = ? AND rs_reputations.active = ?"
+
+ def build_select_statement(table_name, reputation_name, select=nil, srn=nil, normalize=false)
+ select = sanitize_sql_array(["%s.*", table_name]) unless select
+ if normalize
+ max = RSReputation.max(srn, self.name)
+ min = RSReputation.min(srn, self.name)
+ range = max - min
+ if range < DELTA
+ sanitize_sql_array(["%s, (0) AS normalized_%s", select, reputation_name])
+ else
+ sanitize_sql_array(["%s, ((rs_reputations.value - %s) / %s) AS normalized_%s", select, min, range, reputation_name])
+ end
+ else
+ sanitize_sql_array(["%s, COALESCE(rs_reputations.value, 0) AS %s", select, reputation_name])
+ end
+ end
+
+ def build_select_statement_with_reputation_only(table_name, reputation_name, srn=nil, normalize=false)
+ if normalize
+ max = RSReputation.max(srn, self.name)
+ min = RSReputation.min(srn, self.name)
+ range = max - min
+ if range < DELTA
+ sanitize_sql_array(["(0) AS normalized_%s", reputation_name])
+ else
+ sanitize_sql_array(["((rs_reputations.value - %s) / %s) AS normalized_%s", min, range, reputation_name])
+ end
+ else
+ sanitize_sql_array(["COALESCE(rs_reputations.value, 0) AS %s", reputation_name])
+ end
+ end
+
+ def build_condition_statement(conditions=nil)
+ conditions ||= [""]
+ conditions = [conditions] unless conditions.is_a? Array
+ conditions
+ end
+
+ def build_join_statement(table_name, class_name, srn, joins=nil)
+ joins ||= []
+ joins = [joins] unless joins.is_a? Array
+ rep_join = sanitize_sql_array([REPUTATION_JOIN_STATEMENT, class_name.to_s, srn.to_s, true])
+ rep_join = sanitize_sql_array([rep_join, table_name])
+ joins << rep_join
+ end
+ end
+ end
+end
@@ -0,0 +1,61 @@
+##
+# Copyright 2012 Twitter, Inc
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+##
+
+module ReputationSystem
+ module QueryMethods
+ def self.included(klass)
+ klass.extend ClassMethods
+ end
+
+ module ClassMethods
+ def with_reputation(*args)
+ reputation_name, srn = parse_arel_query_args(args)
+ select = build_select_statement(table_name, reputation_name)
+ joins = build_join_statement(table_name, name, srn)
+ self.select(select).joins(joins)
+ end
+
+ def with_reputation_only(*args)
+ reputation_name, srn = parse_arel_query_args(args)
+ select = build_select_statement_with_reputation_only(table_name, reputation_name)
+ joins = build_join_statement(table_name, name, srn)
+ self.select(select).joins(joins)
+ end
+
+ def with_normalized_reputation(*args)
+ reputation_name, srn = parse_arel_query_args(args)
+ select = build_select_statement(table_name, reputation_name, nil, srn, true)
+ joins = build_join_statement(table_name, name, srn)
+ self.select(select).joins(joins)
+ end
+
+ def with_normalized_reputation_only(*args)
+ reputation_name, srn = parse_arel_query_args(args)
+ select = build_select_statement_with_reputation_only(table_name, reputation_name, srn, true)
+ joins = build_join_statement(table_name, name, srn)
+ self.select(select).joins(joins)
+ end
+
+ protected
+
+ def parse_arel_query_args(args)
+ reputation_name = args[0]
+ srn = ReputationSystem::Network.get_scoped_reputation_name(name, reputation_name, args[1])
+ [reputation_name, srn]
+ end
+ end
+ end
+end
@@ -1,27 +0,0 @@
-##
-# Copyright 2012 Twitter, Inc
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-##
-
-require 'spec_helper'
-
-describe ActiveRecord::Base do
-
- before(:each) do
- @user = User.create!(:name => 'jack')
- @question = Question.create!(:text => 'Does this work?', :author_id => @user.id)
- @answer = Answer.create!(:text => 'Yes!', :author_id => @user.id, :question_id => @question.id)
- @phrase = Phrase.create!(:text => "One")
- end
-end
Oops, something went wrong.

0 comments on commit e131cfd

Please sign in to comment.