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

ActiveRecord 4.1 compatibility (take 2) #446

Merged
merged 3 commits into from
Dec 27, 2013
Merged
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
1 change: 1 addition & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ env:
gemfile:
- gemfiles/rails_3.2.gemfile
- gemfiles/rails_4.0.gemfile
- gemfiles/rails_4.1.gemfile
cache: bundler
script: bundle exec rake
before_install:
Expand Down
4 changes: 4 additions & 0 deletions Appraisals
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,7 @@ end
appraise "rails-4.0" do
gem "rails", "~> 4.0"
end

appraise "rails-4.1" do
gem "rails", "~> 4.1.0.beta1"
end
7 changes: 7 additions & 0 deletions gemfiles/rails_4.1.gemfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
# This file was generated by Appraisal

source "https://rubygems.org"

gem "rails", "~> 4.1.0.beta1"

gemspec :path=>"../"
13 changes: 10 additions & 3 deletions lib/acts_as_taggable_on/acts_as_taggable_on/collection.rb
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ def all_tags(options = {})
tagging_scope = tagging_scope.where("#{ActsAsTaggableOn::Tagging.table_name}.taggable_id IN(#{safe_to_sql(select(scoped_select))})").group(group_columns)

tag_scope = tag_scope.joins("JOIN (#{safe_to_sql(tagging_scope)}) AS #{ActsAsTaggableOn::Tagging.table_name} ON #{ActsAsTaggableOn::Tagging.table_name}.tag_id = #{ActsAsTaggableOn::Tag.table_name}.id")
tag_scope
tag_scope.extending(CalculationMethods)
Copy link
Collaborator

Choose a reason for hiding this comment

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

I think this will break the method cache by extending the association proxy whenever this method is called. Couldn't we just monkey patch ActsAsTaggableOn::Tag or extend its association as per http://guides.rubyonrails.org/association_basics.html#association-extensions ?

end

##
Expand Down Expand Up @@ -170,7 +170,7 @@ def all_tag_counts(options = {})
tagging_scope = tagging_scope.group(group_columns).having(having)

tag_scope = tag_scope.joins("JOIN (#{safe_to_sql(tagging_scope)}) AS #{ActsAsTaggableOn::Tagging.table_name} ON #{ActsAsTaggableOn::Tagging.table_name}.tag_id = #{ActsAsTaggableOn::Tag.table_name}.id")
tag_scope
tag_scope.extending(CalculationMethods)
end

def safe_to_sql(relation)
Expand All @@ -183,5 +183,12 @@ def tag_counts_on(context, options={})
self.class.tag_counts_on(context, options.merge(:id => id))
end
end

module CalculationMethods
def count
# https://github.com/rails/rails/commit/da9b5d4a8435b744fcf278fffd6d7f1e36d4a4f2
super(:all)
end
end
end
end
end
18 changes: 9 additions & 9 deletions lib/acts_as_taggable_on/acts_as_taggable_on/core.rb
Original file line number Diff line number Diff line change
Expand Up @@ -104,14 +104,14 @@ def tagged_with(tags, options = {})
tags_conditions = tag_list.map { |t| sanitize_sql(["#{ActsAsTaggableOn::Tag.table_name}.name #{like_operator} ?", t]) }.join(" OR ")
end

conditions << "#{table_name}.#{primary_key} NOT IN (SELECT #{ActsAsTaggableOn::Tagging.table_name}.taggable_id FROM #{ActsAsTaggableOn::Tagging.table_name} JOIN #{ActsAsTaggableOn::Tag.table_name} ON #{ActsAsTaggableOn::Tagging.table_name}.tag_id = #{ActsAsTaggableOn::Tag.table_name}.#{ActsAsTaggableOn::Tag.primary_key} AND (#{tags_conditions}) WHERE #{ActsAsTaggableOn::Tagging.table_name}.taggable_type = #{quote_value(base_class.name)})"
conditions << "#{table_name}.#{primary_key} NOT IN (SELECT #{ActsAsTaggableOn::Tagging.table_name}.taggable_id FROM #{ActsAsTaggableOn::Tagging.table_name} JOIN #{ActsAsTaggableOn::Tag.table_name} ON #{ActsAsTaggableOn::Tagging.table_name}.tag_id = #{ActsAsTaggableOn::Tag.table_name}.#{ActsAsTaggableOn::Tag.primary_key} AND (#{tags_conditions}) WHERE #{ActsAsTaggableOn::Tagging.table_name}.taggable_type = #{quote_value(base_class.name, nil)})"

if owned_by
joins << "JOIN #{ActsAsTaggableOn::Tagging.table_name}" +
" ON #{ActsAsTaggableOn::Tagging.table_name}.taggable_id = #{quote}#{table_name}#{quote}.#{primary_key}" +
" AND #{ActsAsTaggableOn::Tagging.table_name}.taggable_type = #{quote_value(base_class.name)}" +
" AND #{ActsAsTaggableOn::Tagging.table_name}.tagger_id = #{quote_value(owned_by.id)}" +
" AND #{ActsAsTaggableOn::Tagging.table_name}.tagger_type = #{quote_value(owned_by.class.base_class.to_s)}"
" AND #{ActsAsTaggableOn::Tagging.table_name}.taggable_type = #{quote_value(base_class.name, nil)}" +
" AND #{ActsAsTaggableOn::Tagging.table_name}.tagger_id = #{quote_value(owned_by.id, nil)}" +
" AND #{ActsAsTaggableOn::Tagging.table_name}.tagger_type = #{quote_value(owned_by.class.base_class.to_s, nil)}"
end

elsif options.delete(:any)
Expand All @@ -134,11 +134,11 @@ def tagged_with(tags, options = {})

tagging_join = "JOIN #{ActsAsTaggableOn::Tagging.table_name} #{taggings_alias}" +
" ON #{taggings_alias}.taggable_id = #{quote}#{table_name}#{quote}.#{primary_key}" +
" AND #{taggings_alias}.taggable_type = #{quote_value(base_class.name)}"
" AND #{taggings_alias}.taggable_type = #{quote_value(base_class.name, nil)}"
tagging_join << " AND " + sanitize_sql(["#{taggings_alias}.context = ?", context.to_s]) if context

# don't need to sanitize sql, map all ids and join with OR logic
conditions << tags.map { |t| "#{taggings_alias}.tag_id = #{quote_value(t.id)}" }.join(" OR ")
conditions << tags.map { |t| "#{taggings_alias}.tag_id = #{quote_value(t.id, nil)}" }.join(" OR ")
select_clause = "DISTINCT #{table_name}.*" unless context and tag_types.one?

if owned_by
Expand All @@ -160,8 +160,8 @@ def tagged_with(tags, options = {})
taggings_alias = adjust_taggings_alias("#{alias_base_name[0..11]}_taggings_#{sha_prefix(tag.name)}")
tagging_join = "JOIN #{ActsAsTaggableOn::Tagging.table_name} #{taggings_alias}" +
" ON #{taggings_alias}.taggable_id = #{quote}#{table_name}#{quote}.#{primary_key}" +
" AND #{taggings_alias}.taggable_type = #{quote_value(base_class.name)}" +
" AND #{taggings_alias}.tag_id = #{quote_value(tag.id)}"
" AND #{taggings_alias}.taggable_type = #{quote_value(base_class.name, nil)}" +
" AND #{taggings_alias}.tag_id = #{quote_value(tag.id, nil)}"

tagging_join << " AND " + sanitize_sql(["#{taggings_alias}.context = ?", context.to_s]) if context

Expand All @@ -183,7 +183,7 @@ def tagged_with(tags, options = {})
if options.delete(:match_all)
joins << "LEFT OUTER JOIN #{ActsAsTaggableOn::Tagging.table_name} #{taggings_alias}" +
" ON #{taggings_alias}.taggable_id = #{quote}#{table_name}#{quote}.#{primary_key}" +
" AND #{taggings_alias}.taggable_type = #{quote_value(base_class.name)}"
" AND #{taggings_alias}.taggable_type = #{quote_value(base_class.name, nil)}"


group_columns = ActsAsTaggableOn::Tag.using_postgresql? ? grouped_column_names_for(self) : "#{table_name}.#{primary_key}"
Expand Down