Skip to content
This repository has been archived by the owner on Mar 19, 2021. It is now read-only.

Commit

Permalink
Merge pull request mbleigh#339 from shekibobo/dirty-context-tags
Browse files Browse the repository at this point in the history
Fix dirty checking for subsequent calls to taggable_on. Fixes mbleigh#321.
  • Loading branch information
tilsammans committed Apr 14, 2013
2 parents 0ec07ef + b5326f6 commit 6cf57d3
Show file tree
Hide file tree
Showing 4 changed files with 118 additions and 45 deletions.
6 changes: 3 additions & 3 deletions lib/acts_as_taggable_on/acts_as_taggable_on/core.rb
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ def initialize_acts_as_taggable_on_core
context_taggings = "#{tag_type}_taggings".to_sym
context_tags = tags_type.to_sym
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
# the associations tag_taggings & tags are always returned in created order
Expand All @@ -30,7 +30,7 @@ def initialize_acts_as_taggable_on_core
:class_name => "ActsAsTaggableOn::Tagging",
:conditions => ["#{ActsAsTaggableOn::Tagging.table_name}.context = ?", tags_type],
:order => taggings_order

has_many context_tags, :through => context_taggings,
:source => :tag,
:class_name => "ActsAsTaggableOn::Tag",
Expand All @@ -57,7 +57,7 @@ def taggable_on(preserve_tag_order, *tag_types)
super(preserve_tag_order, *tag_types)
initialize_acts_as_taggable_on_core
end

# all column names are necessary for PostgreSQL group clause
def grouped_column_names_for(object)
object.column_names.map { |column| "#{object.table_name}.#{column}" }.join(", ")
Expand Down
2 changes: 1 addition & 1 deletion lib/acts_as_taggable_on/acts_as_taggable_on/dirty.rb
Original file line number Diff line number Diff line change
Expand Up @@ -34,4 +34,4 @@ def #{tag_type}_list_changes
end
end
end
end
end
15 changes: 9 additions & 6 deletions lib/acts_as_taggable_on/taggable.rb
Original file line number Diff line number Diff line change
Expand Up @@ -88,14 +88,17 @@ def self.taggable?
end

include ActsAsTaggableOn::Utils
include ActsAsTaggableOn::Taggable::Core
include ActsAsTaggableOn::Taggable::Collection
include ActsAsTaggableOn::Taggable::Cache
include ActsAsTaggableOn::Taggable::Ownership
include ActsAsTaggableOn::Taggable::Related
include ActsAsTaggableOn::Taggable::Dirty
end
end

# each of these add context-specific methods and must be
# called on each call of taggable_on
include ActsAsTaggableOn::Taggable::Core
include ActsAsTaggableOn::Taggable::Collection
include ActsAsTaggableOn::Taggable::Cache
include ActsAsTaggableOn::Taggable::Ownership
include ActsAsTaggableOn::Taggable::Related
include ActsAsTaggableOn::Taggable::Dirty
end

end
Expand Down
140 changes: 105 additions & 35 deletions spec/acts_as_taggable_on/taggable_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -5,29 +5,29 @@
clean_database!
@taggable = OrderedTaggableModel.new(:name => "Bob Jones")
end

it "should have tag types" do
[:tags, :colours].each do |type|
OrderedTaggableModel.tag_types.should include type
end

@taggable.tag_types.should == OrderedTaggableModel.tag_types
end

it "should have tag associations" do
[:tags, :colours].each do |type|
@taggable.respond_to?(type).should be_true
@taggable.respond_to?("#{type.to_s.singularize}_taggings").should be_true
end
end

it "should have tag associations ordered by id" do
[:tags, :colours].each do |type|
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

it "should have tag methods" do
[:tags, :colours].each do |type|
@taggable.respond_to?("#{type.to_s.singularize}_list").should be_true
Expand All @@ -40,69 +40,69 @@
# create
@taggable.tag_list = "rails, ruby, css"
@taggable.instance_variable_get("@tag_list").instance_of?(ActsAsTaggableOn::TagList).should be_true

lambda {
@taggable.save
}.should change(ActsAsTaggableOn::Tag, :count).by(3)

@taggable.reload
@taggable.tag_list.should == %w(rails ruby css)

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

@taggable.reload
@taggable.tag_list.should == %w(pow ruby rails)

# update with no change
@taggable.tag_list = "pow, ruby, rails"
@taggable.save

@taggable.reload
@taggable.tag_list.should == %w(pow ruby rails)

# update to clear tags
@taggable.tag_list = ""
@taggable.save

@taggable.reload
@taggable.tag_list.should == []
end

it "should return tag objects in the order the tags were created" do
# create
@taggable.tag_list = "pow, ruby, rails"
@taggable.instance_variable_get("@tag_list").instance_of?(ActsAsTaggableOn::TagList).should be_true

lambda {
@taggable.save
}.should change(ActsAsTaggableOn::Tag, :count).by(3)

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

# 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
Expand Down Expand Up @@ -581,24 +581,94 @@
end

describe "Dirty Objects" do
before(:each) do
@taggable = TaggableModel.create(:tag_list => "awesome, epic")
end
context "with un-contexted tags" do
before(:each) do
@taggable = TaggableModel.create(:tag_list => "awesome, epic")
end

it 'should show changes of dirty object' do
@taggable.changes.should == {}
@taggable.tag_list = 'one'
@taggable.changes.should == {"tag_list"=>["awesome, epic", ["one"]]}
context "when tag_list changed" do
before(:each) do
@taggable.changes.should == {}
@taggable.tag_list = 'one'
end

it 'should show changes of dirty object' do
@taggable.changes.should == {"tag_list"=>["awesome, epic", ["one"]]}
end

it 'flags tag_list as changed' do
@taggable.tag_list_changed?.should be_true
end

it 'preserves original value' do
@taggable.tag_list_was.should == "awesome, epic"
end

@taggable.tag_list_changed?.should be_true
@taggable.tag_list_was.should == "awesome, epic"
@taggable.tag_list_change.should == ["awesome, epic", ["one"]]
it 'shows what the change was' do
@taggable.tag_list_change.should == ["awesome, epic", ["one"]]
end
end

context 'when tag_list is the same' do
before(:each) do
@taggable.tag_list = "awesome, epic"
end

it 'is not flagged as changed' do
@taggable.tag_list_changed?.should be_false
end

it 'does not show any changes to the taggable item' do
@taggable.changes.should == {}
end
end
end

it 'should show no changes if the same tag_list' do
@taggable.tag_list = "awesome, epic"
@taggable.tag_list_changed?.should be_false
@taggable.changes.should == {}
context "with context tags" do
before(:each) do
@taggable = TaggableModel.create(:language_list => "awesome, epic")
end

context "when language_list changed" do
before(:each) do
@taggable.changes.should == {}
@taggable.language_list = 'one'
end

it 'should show changes of dirty object' do
@taggable.changes.should == {"language_list"=>["awesome, epic", ["one"]]}
end

it 'flags language_list as changed' do
@taggable.language_list_changed?.should be_true
end

it 'preserves original value' do
@taggable.language_list_was.should == "awesome, epic"
end

it 'shows what the change was' do
@taggable.language_list_change.should == ["awesome, epic", ["one"]]
end

it 'shows what the changes were' do
@taggable.language_list_changes.should == ["awesome, epic", ["one"]]
end
end

context 'when language_list is the same' do
before(:each) do
@taggable.language_list = "awesome, epic"
end

it 'is not flagged as changed' do
@taggable.language_list_changed?.should be_false
end

it 'does not show any changes to the taggable item' do
@taggable.changes.should == {}
end
end
end
end

Expand Down

0 comments on commit 6cf57d3

Please sign in to comment.