我有一个Rails 3.2.18应用程序,我试图通过以下方式将Twilio通知发送到医疗手机的更新操作:
unless @call.call_status == "close" && @call.unit_ids.empty?
如果呼叫状态设置为关闭,则表示呼叫已关闭,并且不需要通过ActionMailer或我的send_sms私有方法发送通知。此外,如果unit_ids为空(单位数组),也不会发出邮件或短信警报。
这里发生了什么。如果呼叫是打开的并且我没有分配单位(unit_ids为空)并且我更新了呼叫,它将绕过动作邮件程序,但它仍然尝试触发send_sms并为@ call.units.first.incharge引发一个nilclass异常因为阵列中不存在军医/充气器。现在如果我在第一个中嵌入另一个除非语句(参见第二个示例工作,如果call_status == close和unit_ids.empty,它将不会触发邮件程序或send_sms?
calls_controller.rb(不工作)
def update
parse_times!
@call = Call.find(params[:id])
respond_to do |format|
if @call.update_attributes(params[:call])
unless (@call.call_status == "close" && @call.unit_ids.empty?)
send_sms
@call.send_mail(:update_call)
end
format.html { redirect_to @call, notice: "Call #{@call.incident_number} was successfully updated.".html_safe }
format.json { head :no_content }
else
format.html { render action: "edit" }
format.json { render json: @call.errors, status: :unprocessable_entity }
end
end
end
private
def send_sms
account_sid = 'AACCCCCC'
auth_token = 'ATttttt'
@client = Twilio::REST::Client.new account_sid, auth_token
@client.account.messages.create(
:from => '2814084444',
:to => @call.units.first.incharge.medic_phone,
:body => "incident_number #{@call.incident_number} patient name #{@call.patient_name}"
)
@client.account.messages.create(
:from => '2814084444',
:to => @call.units.first.attendant.medic_phone,
:body => "incident_number #{@call.incident_number} patient name #{@call.patient_name}"
)
end
end
calls_controller.rb(工作)
def update
parse_times!
@call = Call.find(params[:id])
respond_to do |format|
if @call.update_attributes(params[:call])
unless @call.call_status == "close"
unless @call.unit_ids.empty?
send_sms
end
@call.send_mail(:update_call)
end
format.html { redirect_to @call, notice: "Call #{@call.incident_number} was successfully updated.".html_safe }
format.json { head :no_content }
else
format.html { render action: "edit" }
format.json { render json: @call.errors, status: :unprocessable_entity }
end
end
end
def send_sms
account_sid = 'ACCCCCC'
auth_token = 'atttt'
@client = Twilio::REST::Client.new account_sid, auth_token
@client.account.messages.create(
:from => '2814084444',
:to => @call.units.first.incharge.medic_phone,
:body => "incident_number #{@call.incident_number} patient name #{@call.patient_name}"
)
@client.account.messages.create(
:from => '2814084444',
:to => @call.units.first.attendant.medic_phone,
:body => "incident_number #{@call.incident_number} patient name #{@call.patient_name}"
)
end
将除非语句嵌套为正确的方法,或者我能以某种方式将&&运营商除非。也许我的语法在第一个(非工作)示例中是错误的。我在这里显然遗漏了一些东西,所以提供的任何帮助都会受到赞赏。
更新:08/03 / 14-08:03
似乎如果我使用||运算符我不会引发nilclass异常,并且mailer和send_sms会触发,除非调用状态为close或者调用unit_ids为空。
unless (@call.call_status == "close" || @call.unit_ids.empty?)
send_sms
@call.send_mail(:update_call)
end
这是否有意义,或者我应该尝试使用&&操作
答案 0 :(得分:3)
正如您所正确观察到的,嵌套两个条件等同于将条件与&&
组合。由于unless ...
与if ! ...
相同("如果不是"),您也可以写:
if !(@call.call_status == "close") && !(@call.unit_ids.empty?)
# ...
end
De Morgan's Law告诉我们!a && !b
与!(a || b)
相同:
if !(@call.call_status == "close" || @call.unit_ids.empty?)
# ...
end
当然,我们可以用if !
代替unless
:
unless @call.call_status == "close" || @call.unit_ids.empty?
# ...
end
虽然我建议您使用复杂条件的if
,因为这通常更容易阅读和理解。我们再次开始消除unless
:
if !(@call.call_status == "close") && !(@call.unit_ids.empty?)
# ...
end
然后,我们重新制定&&
左右部分,以便不再需要!
。在这种情况下,我们可以将==
更改为!=
。我们也可以将empty?
更改为any?
,但如果数组仅包含nil
和/或false
值,则会出现问题。如果您确定这种情况从未发生过,那么您也可以使用x.any?
代替! x.empty?
:
if @call.call_status != "close" && !@call.unit_ids.empty?
# ...
end
# If you are 100% sure that @call.unit_ids _never_ contains nil or false values,
# you can use x.any? instead of !x.empty?
if @call.call_status != "close" && @call.unit_ids.any?
# ...
end