我在参数中向控制器发送了一个属性数组,如果在创建记录时出现任何错误,我需要处理验证错误。
因为我需要一次创建多个组。
参数
Parameters: {"group"=>[{"sort_by"=>"id", "template_ids"=>[182], "name"=>"Csdfwses", "count"=>1}, {"sort_by"=>"id", "template_ids"=>[181], "name"=>"rthydrt", "count"=>1}]}
所以我的控制器的create
方法是这样的:
def create
@groups = Group.create group_params
if @groups
render json: { success: true, message: "#{@groups.length} groups created" }
else
render_422 @groups, 'Could not save groups.'
end
end
如果在创建任何记录时发生任何错误,我想处理此案例,以便在创建后显示错误消息。
使用上述方法,此处无法使用error
方法。如何显示错误消息?
我尝试使用begin-rescue:
def create
begin
@groups = Group.create! group_params
if @groups
render json: { success: true, message: "#{@groups.length} groups created" }
else
render_422 @groups, 'Could not save groups.'
end
rescue ActiveRecord::RecordInvalid => invalid
render json: { success: false, message: "#{invalid.record.errors.messages}" }, status: 500
end
end
但我正在寻找更清洁的方法吗?
答案 0 :(得分:5)
您通常会使用accepts_nested_attributes
- 但这需要某种层次关系:
class Company < ActiveRecord::Base
has_many :employees
accepts_nested_records_for :employees
validates_associated :employees
end
class Employee < ActiveRecord::Base
belongs_to :company
validates_presence_of :name
end
c = Company.new(name: 'Acme', employee_attributes: [
{ name: 'Wile E. Coyotee' },
{ name: 'Bugs Bunny' },
{ name: nil } # invalid
])
c.valid? # false
c.save # false
那么如果没有父模型,你会怎么做?创建一个像父关联一样的模型:
# A fake parent model for groups.
# This is not a ActiveRecord model
# It's is not backed by a database table.
class GroupCollection
include ActiveModel::Model
attr_accessor :groups
def initialize(groups_attributes: [], **kw_args)
super
end
# mimics behavior of accepts_nested_attributes
# takes either an array or a key/val hash:
# { 1 => {'name' => 'foo'} }
def groups_attributes=(attrs)
# normalize key/val hash
attrs = attrs.values if attrs.is_a?(Hash)
self.groups = attrs.map {|h| Group.new(h) }
end
# mimics behavior of validates_associated
def valid?
errors.clear
# alternatively you can aggregate errors for
# the nested records on the parent object
if groups.reject { |g| g.valid? }.any?
errors.add(:groups, 'are invalid.')
end
errors.none?
end
def save
return false unless valid?
save_in_transaction
end
def save!
raise ActiveRecord::RecordInvalid and return unless valid?
save_in_transaction
end
private
def save_in_transaction
# use a transaction so changes are rolled back if a save fails.
Group.transaction do
groups.reject { |g| g.save! }.none?
end
end
end
class GroupsController
def create
@collection = GroupCollection.new(groups_params)
@groups = @collection.groups
if @collection.save
c = @groups.length
render json: {
success: true, # anti-pattern! - rely on the response code instead
message: "#{c} #{pluralize(c, 'group')} created"
}, status: :created
else
# you can get the error messages by iterating through @groups
# and calling `.errors.full_messages` on each
render_422 @groups, 'Could not save groups.'
end
end
def collection_params
params.permit(groups_attributes: [:name, :foo, :bar])
end
end
答案 1 :(得分:4)
您希望将哈希数组传递给model.create
,以便一次创建多个记录。
def create
@groups = Group.create group_params
if @groups.all? { |group| group.persisted? }
render json: { success: true, message: "#{@groups.length} groups created" }
else
render_422 @groups, 'Could not save groups.'
end
end
如果您想显示任何验证错误,那么您需要查看model.errors
或查看一系列错误,您可以查看model.errors.full_messages
。
def create
@groups = Group.create group_params
if @groups.all? { |group| group.persisted? }
render json: { success: true, message: "#{@groups.length} groups created" }
else
errors = @groups.map { |group| group.errors.full_messages.empty? nil : group.errors.full_messages }.compact.join("<br/>") # gross one-liner to show you where the errors live
render_422 @groups, "Could not save groups. Here are the errors: #{errors}"
end
end
您需要更好地格式化错误,但这是一个简单的示例。