2

I'm trying to implement a tagging feature to my Post model in my rails app. I'm currently working through the logic to allow a user to add a comma separated list of values and then I parse them and create a Tag record for every one.

The create method works fine, but now i'm trying to create logic so when a user updates the tags for a Post, it actually adds and removes any tags that have been updated.

I have the logic below, but my array current_tag_names does not seem be correctly updating.

The scenario i'm trying is a user creates a post with the tags "One", and "Two", then updates the post and adds tags "Three", and "Four", but when saving the post, it actually removes tags "One", and "Two" when it shouldn't be. This line doesn't seem to be working correctly current_tag_names - [tag] because after you execute it, current_tag_names still contains ["one", "two"].

# Returns 2 tag objects with the names being "one", "two"
db_tags = Tag.where(:post_id => @post.id)

# current_tag_names = ['one', 'two']
current_tag_names = []

# Loop through the db_tags and put just the "name" into an array called current_tag_names
db_tags.each do |db_tag|
   current_tag_names << db_tag.name
end


p "current_tag_names before loop = #{current_tag_names}"  # Verify current_tag_names actually contains ["one", "two"]

tags.each do |tag|

      if current_tag_names.include?(tag)
        p "inside if before #{current_tag_names}"
        current_tag_names - [tag]  # The first time through the loop, this line should remove "one" so that current_tag_names only contains "two" RIGHT??? 
        p "inside if after #{current_tag_names}"
      else
        Tag.create(:name => tag.strip, :post_id => @post.id)
      end

    end
  p "current_tag_names after loop = #{current_tag_names}" # STILL CONTAINS ["one", "two"] here. WTF??
  Tag.where(:name => current_tag_names).where(:post_id => @post.id).destroy_all

I'm using ruby 2.0.0p247 and rails 4.0.0. Is this a bug with either of those or am I doing something totally wrong?

3 Answers 3

2

The problem in your logic is that you're not modifying current_tag_names. Try this:

current_tag_names = current_tag_names - [tag]
Sign up to request clarification or add additional context in comments.

Comments

2

This line has an issue:

current_tag_names - [tag]

The subtraction method does not modify the reciever. Instead, it returns a new array that is the result of the receiver minus the argument. Since you're not reassigning current_tag_names, the variable doesn't actually change.

You have a few options here: use a method that does modify the receiver, like delete:

current_tag_names.delete(tag)

...or simply assign it to the result of the subtraction:

current_tag_names = current_tag_names - [tag]

2 Comments

I tried using delete, but either it wasn't working like I was expecting or my logic wasn't quite right.
@Catfish current_tag_names.delete(tag) will return tag while it also modifies the array.
1

After You current_tag_names - [tag], it doesnt look like you store it. Try:

current_tag_names = current_tag_names - [tag]

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.