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

jam*_*mes 6 ruby activerecord ruby-on-rails

我只是想了解我在 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
Run Code Online (Sandbox Code Playgroud)

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

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
Run Code Online (Sandbox Code Playgroud)

为什么resource.persisted?在 if 语句中进行设计检查而不是resource.save?你什么时候想使用一个?

谢谢!

Rub*_*der 7

Object#persisted?检查数据库中是否存在对象。

Object#save对数据库进行更改,根据操作结果返回 true 或 false,并在失败时向该活动记录对象包含错误消息。

实施例A

成功保存新记录将使其持久化:

if new_object.save
  # It's successfully saved (and persisted)
  assert new_object.persisted?
else
  # It's not saved, therefore not persisted
   assert_not new_object.persisted? 
end
Run Code Online (Sandbox Code Playgroud)

实施例B

保存现有记录(编辑它)不会改变其持久性:

# The record is already in the DB, so it is persisted
assert record.persisted?

if record.save
  # update succeeded
else
  # update failed 
end

assert record.persisted?
Run Code Online (Sandbox Code Playgroud)

  • 所以我从概念上理解你所说的;就像我理解这些方法的作用之间的差异,但是你能帮助我理解什么时候你会使用一种方法而不是另一种方法吗?例如,为什么 Devise 使用 .persisted?并且不保存?因为他们也会渲染错误...... (4认同)

Mic*_*Mic 5

在 Devise 中这样编写的原因是因为他们想要在函数的其余部分yield之间进行调用。save因此他们不能使用if resource.save,而是save使用persisted?call 检查调用是否成功。

Ruby 的“yield row if block_given?”yield ... if block_given?做什么?给出了很好的解释。