我是Rails的新手(和Ruby一样)。如果用户将他/她的手机号码添加到她的帐户,我正试图通过Twilio触发短信进行验证:
def update
authorize! :update, @user, :message => 'Not authorized as an administrator.'
@user = User.find(params[:id])
role = Role.find(params[:user][:role_ids]) unless params[:user][:role_ids].nil?
params[:user] = params[:user].except(:role_ids)
if @user.update_attributes(params[:user])
if @user.mobile_changed?
@user.update_attribute(:mobile_verified, false)
#:message => 'You will receive an SMS shortly with verification instructions.'
# Instantiate a Twilio client
client = Twilio::REST::Client.new(TWILIO_CONFIG['sid'], TWILIO_CONFIG['token'])
# Create and send an SMS message
client.account.sms.messages.create(
from: TWILIO_CONFIG['from'],
to: @user.mobile,
body: "Thanks for adding your mobile number. To verify, please reply YES to this message."
)
end
@user.update_plan(role) unless role.nil?
redirect_to users_path, :notice => "User updated."
else
redirect_to users_path, :alert => "Unable to update user."
end
end
该帐户似乎更新正常,但我的嵌套“if”语句显然是不正确的,因为它不起作用...任何建议?谢谢!
答案 0 :(得分:2)
将after_save(或after_update)回调添加到您的用户模型。更改的属性将在那里提供。
注意:您不应该从after_save回调更新当前记录,因为您可能会以无限循环结束。
class User < ActiveRecord
before_save :reset_mobile_verification, :if => :mobile_verified_changed?
after_save :deliver_sms, :if => :mobile_changed?
def reset_mobile_verification
self.mobile_verified = false
end
def deliver_sms
# Code to send SMS
end
end
我看到另一个答案已更新,以执行类似的操作,但使用after_commit回调。根据您希望应用程序的行为方式,您可以使用after_save(Twilio API错误将导致保存失败)或after_commit(Twilio API错误将不导致保存失败,因为它发生在数据库COMMIT)。
答案 1 :(得分:1)
ActiveModel::Dirty
方法很棘手,它们只会在对象脏时返回true,即,当一个或多个属性已被更改但在这些更改之前已写入数据库。保存对象后,例如第一次if
语句对update_attributes
的调用,它就不再是脏的,named_changed?
将返回false。为了让if
工作,我建议if @user.previous_changes.include?(:mobile)
。
编辑 - 此外,您还可以使用回调将此业务逻辑移至模型。
before_validation ->(user) { user.mobile_verified = false if user.mobile_changed? }
after_commit :send_twilio_verification, :unless => :mobile_verified, on: [:create, :update]