【问题标题】:Rails - has_many through relation saved without saving parentRails - has_many 通过关系保存而不保存父级
【发布时间】:2016-04-11 14:30:09
【问题描述】:

我正在使用 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

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

我尝试了

如何确保post_tag记录只有在post记录被保存的情况下才被保存

【问题讨论】:

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


    【解决方案1】:

    【讨论】:

    • 感谢@edvin。我会检查交易。但是“ false”有什么用
    【解决方案2】:

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

    @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
    

    【讨论】:

    • 感谢@faron。我会检查交易。但是那么 false 有什么用
    • Autosave 将在调用 parent.save 时对加载的记录调用 save。前任。 post = Post.first; post.tags.to_a; post.save 将在每个标签上调用 save
    【解决方案3】:

    当你使用 self.tags = [TagsCollection] 或 self.tags

    当您调用 @post.save 时,它​​会运行验证并向您显示错误。

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

    【讨论】:

      猜你喜欢
      • 2015-12-13
      • 2013-11-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-08-24
      • 1970-01-01
      • 2016-10-17
      • 1970-01-01
      相关资源
      最近更新 更多