代码之家  ›  专栏  ›  技术社区  ›  Daniel Vandersluis

ActiveRecord关联在更新中的记录之前保存

  •  0
  • Daniel Vandersluis  · 技术社区  · 16 年前

    我有一个 Entry 模型中有很多 Tag s 标签 通过在我的表单上的文本框中通过 tag_names 虚拟属性。在对 进入 模型中,标记名字符串将转换为实际值 标签 对象使用 find_or_create_by_name . 这个 标签

    我的入门模型如下所示:

    class Entry < ActiveRecord::Base
      has_many :entry_tags
      has_many :tags, :through => :entry_tags
    
      before_validation :update_tags
    
      attr_writer :tag_names
    
    private
      def update_tags
        if @tag_names
          self.tags = @tag_names.split(",").uniq.map do |name|
            Tag.find_or_create_by_name(name.strip)
          end
        end
      end
    end
    

    进入 对象并为其分配标记,则所有操作都正常工作—如果其中一个上存在验证错误,则不会保存标记 标签 s、 然后返回一条错误消息。但是,如果我尝试用无效标记更新现有条目对象,而不是传回消息,我的 self.tags= update_tags 查找或按名称创建 create ,我得到了同样的结果。

    docs 似乎证实了)这个 tags= 这个电话实际上挽救了我的生命 标签 进入

    2 回复  |  直到 16 年前
        1
  •  2
  •   austinfromboston    16 年前

    我想试试这样的东西:

    class Entry < ActiveRecord::Base
      has_many :entry_tags
      has_many :tags, :through => :entry_tags
    
      before_validation :update_tags
    
      attr_writer :tag_names
      validates_associated :tags
    
    private
      def update_tags
        return unless @tag_names
        current_tag_names = tags.map(&:name)
        user_tag_names = @tag_names.split(",").uniq
        #add in new tags
        user_tag_names.each do |name|
          next if current_tag_names.include?(name)
          tags.build :name => name
        end
        #remove dropped tags
        ( current_tag_names - user_tag_names ).each do |name|
          removed_tag = tags.find_by_name(name)
          tags.delete(removed_tag)
        end
      end
    end
    

    通过这种方式,您只需在应用程序中初始化相关模型 update_tags 操作,因此不会抛出验证错误。我还添加了 validates_associated :tags 因此,这些相关模型上的错误可以通过使用 error_messages_for :entry .

    使现代化 包括用于删除丢弃的标记的代码。

        2
  •  1
  •   Shadwell    16 年前

    update_tags 这将停止服务器上的保存 Entry .

    或者,如果希望避免处理该异常,可以在不存在标记实例的情况下构建一个新的标记实例,并在继续之前检查它是否有效( new_tag.valid? )如果不是,则从返回false 更新标签 .

    推荐文章