Skip to content

Commit

Permalink
Change acts_as_ordered_taggable to return tags in id rather than crea…
Browse files Browse the repository at this point in the history
…ted_at order ...

... to ensure the correct order of tags when all taggings are assigned
the same created_at date/time
  • Loading branch information
Chris Hilton committed Mar 29, 2012
1 parent a12f83a commit 56b36e9
Show file tree
Hide file tree
Showing 4 changed files with 44 additions and 7 deletions.
19 changes: 19 additions & 0 deletions README.rdoc
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,25 @@ directory, you can run the specs for RoR 3.x with:
User.skill_counts # => [<Tag name="joking" count=2>,<Tag name="clowning" count=1>...]
@frankie.skill_counts

To preserve the order in which tags are created use acts_as_ordered_taggable:

class User < ActiveRecord::Base
# Alias for <tt>acts_as_ordered_taggable_on :tags</tt>:
acts_as_ordered_taggable
acts_as_ordered_taggable_on :skills, :interests
end

@user = User.new(:name => "Bobby")
@user.tag_list = "south, east"
@user.save

@user.tag_list = "north, south, east, west"
@user.save

@user.reload
@user.tag_list => ["north", "south", "east", "west"]


=== Finding Tagged Objects

Acts As Taggable On utilizes named_scopes to create an association for tags.
Expand Down
4 changes: 2 additions & 2 deletions lib/acts_as_taggable_on/acts_as_taggable_on/core.rb
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ def initialize_acts_as_taggable_on_core
tag_type = tags_type.to_s.singularize
context_taggings = "#{tag_type}_taggings".to_sym
context_tags = tags_type.to_sym
taggings_order = (preserve_tag_order? ? "#{ActsAsTaggableOn::Tagging.table_name}.created_at" : nil)
taggings_order = (preserve_tag_order? ? "#{ActsAsTaggableOn::Tagging.table_name}.id" : nil)

class_eval do
# when preserving tag order, include order option so that for a 'tags' context
Expand Down Expand Up @@ -248,7 +248,7 @@ def tags_on(context)
scope = base_tags.where(["#{ActsAsTaggableOn::Tagging.table_name}.context = ? AND #{ActsAsTaggableOn::Tagging.table_name}.tagger_id IS NULL", context.to_s])
# when preserving tag order, return tags in created order
# if we added the order to the association this would always apply
scope = scope.order("#{ActsAsTaggableOn::Tagging.table_name}.created_at") if self.class.preserve_tag_order?
scope = scope.order("#{ActsAsTaggableOn::Tagging.table_name}.id") if self.class.preserve_tag_order?
scope.all
end

Expand Down
2 changes: 1 addition & 1 deletion lib/acts_as_taggable_on/acts_as_taggable_on/ownership.rb
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ def owner_tags_on(owner, context)
end
# when preserving tag order, return tags in created order
# if we added the order to the association this would always apply
scope = scope.order("#{ActsAsTaggableOn::Tagging.table_name}.created_at") if self.class.preserve_tag_order?
scope = scope.order("#{ActsAsTaggableOn::Tagging.table_name}.id") if self.class.preserve_tag_order?
scope.all
end

Expand Down
26 changes: 22 additions & 4 deletions spec/acts_as_taggable_on/taggable_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,10 @@
end
end

it "should have tag associations ordered by created_at" do
it "should have tag associations ordered by id" do
[:tags, :colours].each do |type|
OrderedTaggableModel.reflect_on_association(type).options[:order].should include('created_at')
OrderedTaggableModel.reflect_on_association("#{type.to_s.singularize}_taggings".to_sym).options[:order].should include('created_at')
OrderedTaggableModel.reflect_on_association(type).options[:order].should include('id')
OrderedTaggableModel.reflect_on_association("#{type.to_s.singularize}_taggings".to_sym).options[:order].should include('id')
end
end

Expand Down Expand Up @@ -85,10 +85,28 @@
# update
@taggable.tag_list = "rails, ruby, css, pow"
@taggable.save

@taggable.reload
@taggable.tags.map{|t| t.name}.should == %w(rails ruby css pow)
end

it "should return tag objects in tagging id order" do
# create
@taggable.tag_list = "pow, ruby, rails"
@taggable.save

@taggable.reload
ids = @taggable.tags.map{|t| t.taggings.first.id}
ids.should == ids.sort

# update
@taggable.tag_list = "rails, ruby, css, pow"
@taggable.save

@taggable.reload
ids = @taggable.tags.map{|t| t.taggings.first.id}
ids.should == ids.sort
end
end

describe "Taggable" do
Expand Down

0 comments on commit 56b36e9

Please sign in to comment.