Rails ActiveRecord回调:如果存在则更新,如果不存在则创建

时间:2017-12-05 14:41:34

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

在梳理完文档之后,我很难理解我应该使用什么回调。

伪代码:

如果child_id和outage_id不存在

创建一个关系(INSERT语句)

如果outage_id已更改

修改关系(UPDATE语句)

这些插入和更新通过collection_check_boxes

处理

有3种型号。关系,停电和儿童。

class Outage < ApplicationRecord
  has_many :relationships
  has_many :children, through: :relationships
end

class Child < ApplicationRecord
end


class Relationship < ApplicationRecord
  belongs_to :outage
  belongs_to :child

  validate :check_if_exists, if: :outage_id_changed?

  private

  def check_if_exists
    Relationship.where(child_id: self.child_id).update_all(outage_id: self.outage_id)
  end
end

我现在面临的问题是UPDATE始终发生在INSERT之前,无论如何。只有在记录存在且UPDATE发生更改时才会出现outage_id

任何关于我在这里做错的见解都将不胜感激。

1 个答案:

答案 0 :(得分:0)

你可以试试这个,

class Relationship < ApplicationRecord
    before_update :check_if_exists, if: :outage_id_changed?

    private
    def check_if_exists
       # Your logic
    end
end

注意:在您的代码中,check_if_exists也会在创建时运行,因为outage_id在创建期间从nil更改为<some_id>

但是,使用before_update将确保其仅在更新时运行

另请注意,您正在使用update_all,这会导致直接数据库查询,并且不会包含在事务中。意思是,如果更新失败,则不会回滚通过update_all进行的更改