3

I am using virtual attributes to save tags in an Entry model from a comma-separated textbox in my form (based on Railscasts #167):

class Entry < ActiveRecord::Base
  has_many :entry_tags
  has_many :tags, :through => :entry_tags

  after_save :update_tags
  attr_writer :tag_names

  def tag_names
    tags.map(&:name).join(", ")
  end

  def update_tags
    if @tag_names
      self.tags = @tag_names.split(",").map do |name|
        Tag.find_or_create_by_name(name.strip)
      end
    end
  end
  private :update_tags
end

I want to add validation on my Tag names, but I'm not sure what the best way to do that would be. I have an existing validation method defined in the Tag model:

class Tag < ActiveRecord::Base
  has_many :entry_tags
  has_many :entries, :through => :entry_tags

  validates_uniqueness_of :name
  validates_format_of :name, :with => /\A[a-z0-9_ -]*\Z/, :on => :create
end

However, because the update_tags method is being called after save, any validation errors from the create would be after the Entry is already saved.

I'm thinking about creating a validation method within the Entry model and calling that on entry save, but:

  1. If I do that, I'm not sure what the best way to do the validation would be. Do I create my own validation within Entry or create a Tag object for each name and check t.valid?? Would I somehow collect validation error messages from Tag or generate them?
  2. I'm not sure if this is even the right way to do this sort of validation.

Any suggestions?

Daniel Vandersluis
  • 91,582
  • 23
  • 169
  • 153

2 Answers2

4

If you haven't ruled it out already, I'd take a look at using validates_associated.

nakajima
  • 1,862
  • 12
  • 12
  • I tried moving my `update_tags` method to be called `before_validation`, and that worked, but it seems like the association is being validated automatically anyways when saving (I was ending up with duplicate error messages for an invalid tag). – Daniel Vandersluis Jul 14 '09 at 16:42
  • Really it was enought to add `validates_associated :tags`? I have the same code , but I get `Failed to replace categories because one or more of the new records could not be saved.` instead of validation notices... – chodorowicz Jul 28 '11 at 14:30
  • @chodorowicz Did you ever figure that one out? I'm getting the same error. – Jason Swett Aug 08 '12 at 17:35
0

This error comes up when you try to add an invalid item to an association. A possible cause is that you added a validation to the associated model after entering data, and you currently have invalid values in the database.

Marek Maurizio
  • 1,073
  • 2
  • 11
  • 22