为什么删除对 full_messages 函数不起作用?
Why does delete not work on full_messages function?
我有以下代码:
def register_learner
@event = Event.find(params[:event_id])
@registation = EventRegistration.new first_name: params[:first_name], last_name: params[:last_name], email: params[:email], event_id: params[:event_id]
if !@registation.valid?
@registation.errors.full_messages.delete("Event has already been taken"
flash[:notice] = @registation.errors.full_messages.to_sentence
redirect_to(event_path(@event))
else
@registation.save
end
end
请注意 @registation.errors.full_messages.delete("Event has already been taken")
行,我试图从 full_messages 数组中删除此特定消息,但它不起作用。下一行是 flash 消息,消息 "Event has already been taken" 仍在显示。
这是通过控制台进行的健全性检查...
2.1.5 :001 > errors = ["Event has already been taken", "Last name can't be blank"]
=> ["Event has already been taken", "Last name can't be blank"]
2.1.5 :002 > errors.delete "Event has already been taken"
=> "Event has already been taken"
2.1.5 :003 > errors
=> ["Last name can't be blank"]
我错过了什么?
这是因为full_messages
是一个方法,每次调用都会生成一个新的数组。做你想做的事:
errors = @registation.errors.full_messages
errors.delete("Event has already been taken")
flash[:notice] = errors.to_sentence
这回答了问题,现在有一个问题 - 你为什么需要这样做?可能有更好的方法。
总的来说,依赖字符串通常不是一个好主意,想象一下,半年后您将需要更改错误消息以进行此验证。你能 100% 确定你也会记得在这里更改它吗?如果没有,你有一个错误。
嗯,因为 Rails 会在您每次调用方法时使用 errors
重新创建 #full_messages
:
def full_messages(options = {})
@errors.values.inject([]) do |full_messages, errors|
full_messages + errors.map { |error| error.full_message }
end
end
您可以使用 #select
跳过该消息:
@registation.errors.full_messages.select{|x| x != "Event has already been taken"}.to_sentence
此外,您可以在 #errors.messages
上使用 #delete
(而不是 full_messages
),因为它们是底层对象的暴露属性(不是副本,与 full_messages):
@registration.errors.messages[:event].delete('has already been taken')
我有以下代码:
def register_learner
@event = Event.find(params[:event_id])
@registation = EventRegistration.new first_name: params[:first_name], last_name: params[:last_name], email: params[:email], event_id: params[:event_id]
if !@registation.valid?
@registation.errors.full_messages.delete("Event has already been taken"
flash[:notice] = @registation.errors.full_messages.to_sentence
redirect_to(event_path(@event))
else
@registation.save
end
end
请注意 @registation.errors.full_messages.delete("Event has already been taken")
行,我试图从 full_messages 数组中删除此特定消息,但它不起作用。下一行是 flash 消息,消息 "Event has already been taken" 仍在显示。
这是通过控制台进行的健全性检查...
2.1.5 :001 > errors = ["Event has already been taken", "Last name can't be blank"]
=> ["Event has already been taken", "Last name can't be blank"]
2.1.5 :002 > errors.delete "Event has already been taken"
=> "Event has already been taken"
2.1.5 :003 > errors
=> ["Last name can't be blank"]
我错过了什么?
这是因为full_messages
是一个方法,每次调用都会生成一个新的数组。做你想做的事:
errors = @registation.errors.full_messages
errors.delete("Event has already been taken")
flash[:notice] = errors.to_sentence
这回答了问题,现在有一个问题 - 你为什么需要这样做?可能有更好的方法。
总的来说,依赖字符串通常不是一个好主意,想象一下,半年后您将需要更改错误消息以进行此验证。你能 100% 确定你也会记得在这里更改它吗?如果没有,你有一个错误。
嗯,因为 Rails 会在您每次调用方法时使用 errors
重新创建 #full_messages
:
def full_messages(options = {})
@errors.values.inject([]) do |full_messages, errors|
full_messages + errors.map { |error| error.full_message }
end
end
您可以使用 #select
跳过该消息:
@registation.errors.full_messages.select{|x| x != "Event has already been taken"}.to_sentence
此外,您可以在 #errors.messages
上使用 #delete
(而不是 full_messages
),因为它们是底层对象的暴露属性(不是副本,与 full_messages):
@registration.errors.messages[:event].delete('has already been taken')