Rails 在 after_initialize 中创建 8 条记录,而它应该创建 2 条记录
Rails creating 8 records in after_initialize when it should create 2
我有一个 after_initialize
方法,它应该在初始化 Conference
时创建 2 个子记录,但它却创建了 8 个(每个 4 个)。它似乎不是多线程错误,但我不确定。
conference.rb
class Conference < ApplicationRecord
has_many :tracks, dependent: :destroy
after_initialize do
initialize_tracks
end
private
def initialize_tracks
one = Track.new(name: 'Track One')
two = Track.new(name: 'Track Two')
tracks << one
tracks << two
end
end
conference_controller#create
def create
@conference = Conference.new(conference_params)
respond_to do |format|
if @conference.save
# lines = input_file.read.split(/\n/)
# lines.each do |line|
# next if line.blank?
# title, length = line.split(/\d|lightning/)
# length = '5min' if length.nil?
# @conference.tracks.first.talks << Talk.new(title: title, length: length.scan(/\d/).first)
# end
format.html { redirect_to @conference, notice: 'Conference was successfully created.' }
format.json { render :show, status: :created, location: @conference }
else
format.html { render :new }
format.json { render json: @conference.errors, status: :unprocessable_entity }
end
end
end
track.rb
# == Schema Information
#
# Table name: tracks
#
# id :integer not null, primary key
# conference_id :integer
# created_at :datetime not null
# updated_at :datetime not null
# name :string
#
class Track < ApplicationRecord
belongs_to :conference
has_many :talks, dependent: :destroy
end
an after_find
and after_initialize
callback is triggered for each object that is found and instantiated by a finder, with after_initialize
being triggered after new objects are instantiated as well.
http://api.rubyonrails.org/classes/ActiveRecord/Callbacks.html
由于您两次实例化对象(可能在控制器中的new
和create
操作上)代码被调用了两次。
您可以考虑 在控制器上构建轨道:
def new
@conference = Conference.new(conference_params)
build_tracks
end
def create
@conference = Conference.new(conference_params)
respond_to do |format|
if @conference.save
format.html { redirect_to @conference, notice: 'Conference was successfully created.' }
format.json { render :show, status: :created, location: @conference }
else
build_tracks
format.html { render :new }
format.json { render json: @conference.errors, status: :unprocessable_entity }
end
end
end
private
def build_tracks
return if @conference.tracks.any?
track_names = ['Track One', 'Track Two']
track_names.each do |track_name|
conference.tracks.build(name: track_name)
end
end
我有一个 after_initialize
方法,它应该在初始化 Conference
时创建 2 个子记录,但它却创建了 8 个(每个 4 个)。它似乎不是多线程错误,但我不确定。
conference.rb
class Conference < ApplicationRecord
has_many :tracks, dependent: :destroy
after_initialize do
initialize_tracks
end
private
def initialize_tracks
one = Track.new(name: 'Track One')
two = Track.new(name: 'Track Two')
tracks << one
tracks << two
end
end
conference_controller#create
def create
@conference = Conference.new(conference_params)
respond_to do |format|
if @conference.save
# lines = input_file.read.split(/\n/)
# lines.each do |line|
# next if line.blank?
# title, length = line.split(/\d|lightning/)
# length = '5min' if length.nil?
# @conference.tracks.first.talks << Talk.new(title: title, length: length.scan(/\d/).first)
# end
format.html { redirect_to @conference, notice: 'Conference was successfully created.' }
format.json { render :show, status: :created, location: @conference }
else
format.html { render :new }
format.json { render json: @conference.errors, status: :unprocessable_entity }
end
end
end
track.rb
# == Schema Information
#
# Table name: tracks
#
# id :integer not null, primary key
# conference_id :integer
# created_at :datetime not null
# updated_at :datetime not null
# name :string
#
class Track < ApplicationRecord
belongs_to :conference
has_many :talks, dependent: :destroy
end
an
after_find
andafter_initialize
callback is triggered for each object that is found and instantiated by a finder, withafter_initialize
being triggered after new objects are instantiated as well.
http://api.rubyonrails.org/classes/ActiveRecord/Callbacks.html
由于您两次实例化对象(可能在控制器中的new
和create
操作上)代码被调用了两次。
您可以考虑 在控制器上构建轨道:
def new
@conference = Conference.new(conference_params)
build_tracks
end
def create
@conference = Conference.new(conference_params)
respond_to do |format|
if @conference.save
format.html { redirect_to @conference, notice: 'Conference was successfully created.' }
format.json { render :show, status: :created, location: @conference }
else
build_tracks
format.html { render :new }
format.json { render json: @conference.errors, status: :unprocessable_entity }
end
end
end
private
def build_tracks
return if @conference.tracks.any?
track_names = ['Track One', 'Track Two']
track_names.each do |track_name|
conference.tracks.build(name: track_name)
end
end