Ruby on Rails:如何更新记录的属性,除了一个?

时间:2013-06-24 13:18:02

标签: ruby-on-rails ruby ruby-on-rails-3 ruby-on-rails-3.2

在我的Rails应用中,我有一个update操作users可以用来更新他们的个人资料。

我想要实现的棘手问题是,如果用户输入电子邮件地址并保存,则该电子邮件地址不会立即保存到email数据库字段,而是一个名为new_email的数据库字段。字段email应保持不变(至少在user稍后确认该电子邮件地址之前)。

def update
  current_email = @user.email
  new_email = params[:user][:email].downcase.to_s
  if @user.update_attributes(params[:user])    
    if new_email != current_email
      @user.change_email(current_email, new_email)     
      flash[:success] = "Profile updated. Please confirm your new email by clicking on the link that we've sent you."
    else
      flash[:success] = "Profile updated."
    end
    redirect_to edit_user_path(@user)
  else
    render :edit
  end
end

用户模型:

def change_email(old_email, new_email)
  self.new_email = new_email.downcase 
  self.email = old_email
  self.send_email_confirmation_link
end 

上面的功能有效,但很难测试,感觉不对。是否有更顺畅的方法来实现这一目标?

感谢您的帮助。

2 个答案:

答案 0 :(得分:3)

如果您更改表单以便更新new_email,则可以将其全部放在简单的after_update挂钩中。

after_update :check_new_email

private
  def check_new_email
    send_email_confirmation_link if new_email_changed?
  end

答案 1 :(得分:0)

我认为您可以使用名为“email_input的”虚拟“属性,并在视图中显示此属性的字段(而不是email):

<%= f.text_field :email_input %>

然后在你的模型中你应该:

class User < ActiveRecord::Base
  attr_accessor :email_input
  attr_accessible :email_input
  before_save :set_email, :if => lambda{|p| p.email_input.present?}

  # ...
  def set_email
    email_input.downcase!
    if new_record?
      self.email = email_input
    else
      self.new_email = email_input
      send_email_confirmation_link
    end
  end
end