Rails:如何通过适当的回滚(一种手动嵌套属性)一起更新多个模型
Rails: How to update multiple models together, with proper rollback (kind of manual nested attributes)
我(出于各种原因)决定不使用 nested_attributes
。这是我当前的控制器:
def update
# Update snippet
@snippet.update(snippet_params)
# Update hotspot
@snippet.hotspot.update(hotspot_params)
# Update text
@snippet.text.update(medium_params_with(:text))
# Update audio
if params[:audio] {
@snippet.audio.destroy
@snippet.media << Audio.new(medium_params_with(:audio))
}
respond_to do |format|
if success = true #fix this up
format.html { redirect_to @project, notice: 'Snippet was successfully updated.' }
format.json { render :show, status: :ok, location: @snippet }
else
format.html { redirect_to @project, warning: 'Highlight was not updated.' }
format.json { render json: @snippet.errors, status: :unprocessable_entity }
end
end
end
如果没有问题,这或多或少是可以的。
如何将其包装成如下内容:
try {
update everything
} else {
undo any changes I made while trying to update everything
}
if success {
etc
} else {
etc
}
如果您要更改的是使用 SQL 数据库的 ActiveRecord 模型,那么 http://api.rubyonrails.org/classes/ActiveRecord/Transactions/ClassMethods.html 可能会提供您正在寻找的内容。
根据@Jonah 的回答,我将数据库更改包装在 ActiveRecord::Base.transaction
:
def update
success = ActiveRecord::Base.transaction do
# Update snippet
@snippet.update(snippet_params)
# Update text
@snippet.text.update(medium_params_with(:text))
# Update audio
if params[:audio]
@snippet.audio.destroy
@snippet.media << Audio.new(medium_params_with(:audio))
end
end
respond_to do |format|
if success
format.html { redirect_to @project, notice: 'Snippet was successfully updated.' }
format.json { render :show, status: :ok, location: @snippet }
else
format.html { redirect_to @project, warning: 'Highlight was not updated.' }
format.json { render json: @snippet.errors, status: :unprocessable_entity }
end
end
end
我(出于各种原因)决定不使用 nested_attributes
。这是我当前的控制器:
def update
# Update snippet
@snippet.update(snippet_params)
# Update hotspot
@snippet.hotspot.update(hotspot_params)
# Update text
@snippet.text.update(medium_params_with(:text))
# Update audio
if params[:audio] {
@snippet.audio.destroy
@snippet.media << Audio.new(medium_params_with(:audio))
}
respond_to do |format|
if success = true #fix this up
format.html { redirect_to @project, notice: 'Snippet was successfully updated.' }
format.json { render :show, status: :ok, location: @snippet }
else
format.html { redirect_to @project, warning: 'Highlight was not updated.' }
format.json { render json: @snippet.errors, status: :unprocessable_entity }
end
end
end
如果没有问题,这或多或少是可以的。
如何将其包装成如下内容:
try {
update everything
} else {
undo any changes I made while trying to update everything
}
if success {
etc
} else {
etc
}
如果您要更改的是使用 SQL 数据库的 ActiveRecord 模型,那么 http://api.rubyonrails.org/classes/ActiveRecord/Transactions/ClassMethods.html 可能会提供您正在寻找的内容。
根据@Jonah 的回答,我将数据库更改包装在 ActiveRecord::Base.transaction
:
def update
success = ActiveRecord::Base.transaction do
# Update snippet
@snippet.update(snippet_params)
# Update text
@snippet.text.update(medium_params_with(:text))
# Update audio
if params[:audio]
@snippet.audio.destroy
@snippet.media << Audio.new(medium_params_with(:audio))
end
end
respond_to do |format|
if success
format.html { redirect_to @project, notice: 'Snippet was successfully updated.' }
format.json { render :show, status: :ok, location: @snippet }
else
format.html { redirect_to @project, warning: 'Highlight was not updated.' }
format.json { render json: @snippet.errors, status: :unprocessable_entity }
end
end
end