为什么/何时检查Object.persisted?与Object.save

时间:2015-07-07 18:37:42

标签: ruby-on-rails ruby activerecord

我只是想了解我在Ruby代码中看到过的两种模式。

在Michael Hartl的标准教程中,代码是这样的:

def create
  @user = User.new(params[:user])
  if @user.save
    sign_in @user
    flash[:success] = "Welcome to the Sample App!"
    redirect_to @user
  else
    render 'new'
  end
end

这是我非常习惯的模式。我刚刚实现了Devise,但它的模式是:

def create
  build_resource(sign_up_params)

  resource.save
  yield resource if block_given?
  if resource.persisted?
    if resource.active_for_authentication?
      set_flash_message :notice, :signed_up if is_flashing_format?
      sign_up(resource_name, resource)
      respond_with resource, location: after_sign_up_path_for(resource)
    else
      set_flash_message :notice, :"signed_up_but_#{resource.inactive_message}" if is_flashing_format?
      expire_data_after_sign_in!
      respond_with resource, location: after_inactive_sign_up_path_for(resource)
    end
  else
    clean_up_passwords resource
    set_minimum_password_length
    respond_with resource
  end
end

为什么设计if语句中的resource.persisted?而不是resource.save?什么时候你想用另一个?

谢谢!

2 个答案:

答案 0 :(得分:2)

对象#持续?是检查初始化对象是否持久存储在数据库中?不是吗?

例如:

假设您要编写方法Object#profile。因此,您可能需要查看该对象是否持久化(已在数据库中保存了值)。

iframe

Object#save用于将记录保存到数据库,如果失败则返回true或false,并在该活动记录对象上显示错误消息。所以过去常常这样使用吗?

例如

def profile 
 if self.persisted?
    {
        a: :b,
        c: :d
    }
  end
 end

答案 1 :(得分:1)

在Devise中用这种方式编写代码的原因是因为他们想在yield和函数的其余部分之间调用save。因此他们不能使用if resource.save,而是使用save来检查对persisted?的调用是否成功。

关于yield ... if block_given?的工作,Ruby " yield row if block_given?"给出了很好的解释。