Rails - has_many通过关系保存而不保存父级

时间:2016-04-11 14:30:10

标签: ruby-on-rails ruby rails-activerecord

我正在使用Rails 4.2,最近尝试在我的模型中使用has_many通过关系。我在更新记录时遇到问题而不确定如何处理它。 下面考虑我的模型

class Post < ActiveRecord::Base
  attr_accessor: name

  validates :name, :presence => true
  has_many :post_tags
  has_many :tags, :through => :post_tags, :autosave => false

  def tags_used
    self.tags.collect(&:name).join(',')
  end

  def tags_used=(list)
    self.tags = list.present? ? Tag.where(:name => list.split(/\s*,\s*/)) : [ ]
  end
end

class Tag < ActiveRecord::Base
  has_many :post_tags
  has_many :posts, :through => :post_tags
end

class PostTag < ActiveRecord::Base
  belongs_to :post
  belongs_to :tag
end

现在,如果我通过以下代码更新现有的帖子

@post = Post.find(1)
@post.name = nil
@post.tags_used = ["rails","ruby"]
@post.save

该帖子将无法通过验证,因为名称不能为零。但post_tag记录正在保存。

我试过&lt;&lt;而不是替换=但它没有帮助。

如何确保仅在保存帖子记录时保存post_tag记录

3 个答案:

答案 0 :(得分:0)

您需要将此代码包装在事务中:

@post = Post.find(1)
@post.name = nil
@post.transaction do
  @post.tags_used = ["rails","ruby"]
  raise ActiveRecord::Rollback unless @post.save
  # or just @post.save!
end

答案 1 :(得分:0)

答案 2 :(得分:0)

使用时 self.tags = [TagsCollection]或self.tags&lt;&lt;标签 这将直接在帖子上保存关联的标签。因此,你的标签保存在这里。

当你打电话给@ post.save时,它会运行验证并向你显示错误。

您可以尝试使用嵌套属性,或者在这种情况下使用self.tags.build,以便在保存父级时保存标记。