新手问题 belongs_to 中 accepts_nested_attributes_for 新增一条数据的问题?

jmmbite · 2018年07月27日 · 最后由 jmmbite 回复于 2018年07月29日 · 992 次阅读

有 2 张表,一张 topics,一张 topictexts

第一种方式:是没有问题的。

  • topics: id, title
  • topictexts: id, topic_id, body
# models/topic.rb
class Topic < ApplicationRecord
  has_one :topictext, dependent: :destroy
  accepts_nested_attributes_for :posttext, allow_destroy: true, reject_if: :all_blank, update_only: true
end

# models/topictext.rb
class Topictext < ApplicationRecord
  belongs_to :topic
end

class TopicsController < ApplicationController
  def create
    @topic.create(topic_params)
  end

  private
    def topic_params
      params.require(:topic).permit(:title, topictext_attributes: [:body])
    end
end
  • topic: create
  • topictext: create

第一种方法到这里就结束了

class ApplicationRecord < ActiveRecord::Base
  after_save :trace_log
  after_destroy :trace_log
  def trace_log
    if @_trigger_update_callback
      after_on = 'update'
    elsif @destroyed
      after_on = 'destroy'
    else
      after_on = 'create'
    end
    puts "#{self.class.name}:#{after_on}"
  end
end

第二种方式:在数据结果上也是没有问题。

因为不是每条 topic 都有 topictext,所有打算改一下依赖关系,直接通过 topictext_id 判断书否有 topictext。

  • topics: id, title, topictext_id
  • topictexts: id, body
# models/topic.rb
class Topic < ApplicationRecord
  belongs_to :topictext, dependent: :destroy
  accepts_nested_attributes_for :posttext, allow_destroy: true, reject_if: :all_blank, update_only: true
end

# models/topictext.rb
class Topictext < ApplicationRecord
  has_one :topic, dependent: :nullify, optional: true
end

# 其余不变  

但是在跟踪 class ApplicationRecord < ActiveRecord::Baseafter_save,发现 rails 进行了多一次操作

  • topictext: create
  • topic: create

第二种方法:执行完后,多了下面 2 条操作,由于数据已经写入数据库,实际这 2 次操作,并没有任何影响。

  • topictext: create
  • topic: update

源码也看了一下,找不到头绪,对于强迫症来说有点难受😂 :,有人了解其中原理吗?

https://github.com/rails/rails/blob/master/activerecord/lib/active_record/nested_attributes.rb

补上,class ApplicationRecord < ActiveRecord::Base 代码

class ApplicationRecord < ActiveRecord::Base
  after_save :trace_log
  after_destroy :trace_log
  def trace_log
    if @_trigger_update_callback
      after_on = 'update'
    elsif @destroyed
      after_on = 'destroy'
    else
      after_on = 'create'
    end
    puts "#{self.class.name}:#{after_on}"
  end
end
需要 登录 后方可回复, 如果你还没有账号请 注册新账号