Ruby on rails 铁路及;ActiveRecord-对on::create和on::update进行不同的验证?

Ruby on rails 铁路及;ActiveRecord-对on::create和on::update进行不同的验证?,ruby-on-rails,rails-activerecord,Ruby On Rails,Rails Activerecord,我想要一个具有以下属性的用户模型创建/验证/更新系统: 要求1 首次创建用户时,:名称、:电子邮件和:密码属性应全部存在,否则创建保存应失败 要求2 更新用户时,这三个属性可以单独更新,因此,如果其中一个或两个属性为空,则可以进行更新保存 简单,常见的需求对吗??我不太确定。满足第一个要求的明显方法是在用户模型验证中使用存在:真对所有三个: user.rb validates :name, length: {maximum: 50}, presence: true

我想要一个具有以下属性的
用户
模型创建/验证/更新系统:

要求1

首次创建
用户
时,
:名称
:电子邮件
:密码
属性应全部存在,否则创建保存应失败

要求2

更新
用户
时,这三个属性可以单独更新,因此,如果其中一个或两个属性为空,则可以进行更新保存

简单,常见的需求对吗??我不太确定。满足第一个要求的明显方法是在
用户
模型验证中使用
存在:真
对所有三个:

user.rb

validates :name,      length: {maximum: 50},           presence: true
validates :email, uniqueness: {case_sensitive: false}, presence: true
validates :password,  length: {minimum: 6},            presence: true
validates :name,      length: {maximum: 50},           presence: true
validates :email, uniqueness: {case_sensitive: false}, presence: true
validates :password,  length: {minimum: 6},            presence: true
def update
  params[:user].delete(:name)     if params[:user][:name].blank?
  params[:user].delete(:email)    if params[:user][:email].blank?
  params[:user].delete(:password) if params[:user][:password].blank?

  if @user.update_attributes(update_user_params)
    flash[:success] = "Edit Successful."
    redirect_to @user
  else
    @title = "Edit user"
    render 'edit'
  end
end

def update_user_params
  params.require(:user).permit(:name, :email, :password)
end
validates :name,      length: {maximum: 50}
validates :email, uniqueness: {case_sensitive: false}
validates :password,  length: {minimum: 6}
def update
  params[:user].delete(:name)     if params[:user][:name].blank?
  params[:user].delete(:email)    if params[:user][:email].blank?
  params[:user].delete(:password) if params[:user][:password].blank?

  if @user.update_attributes(update_user_params)
    flash[:success] = "Edit Successful."
    redirect_to @user
  else
    @title = "Edit user"
    render 'edit'
  end
end
validates :name,      length: {maximum: 50},           presence: true, on: :create
validates :email, uniqueness: {case_sensitive: false}, presence: true, on: :create
validates :password,  length: {minimum: 6},            presence: true, on: :create

validates :name,      length: {maximum: 50},           on: :update
validates :email, uniqueness: {case_sensitive: false}, on: :update
validates :password,  length: {minimum: 6},            on: :update
def update
  params[:user].delete(:name)     if params[:user][:name].blank?
  params[:user].delete(:email)    if params[:user][:email].blank?
  params[:user].delete(:password) if params[:user][:password].blank?

  if @user.update_attributes(update_user_params)
    flash[:success] = "Edit Successful."
    redirect_to @user
  else
    @title = "Edit user"
    render 'edit'
  end
end
那么,从这里开始,我们如何满足第二个要求呢

尝试1

on::create
添加到验证:

validates :name,      length: {maximum: 50},           presence: true, on: :create
validates :email, uniqueness: {case_sensitive: false}, presence: true, on: :create
validates :password,  length: {minimum: 6},            presence: true, on: :create
validates :name,      length: {maximum: 50},           presence: true, allow_nil: true
validates :email, uniqueness: {case_sensitive: false}, presence: true, allow_nil: true
validates :password,  length: {minimum: 6},            presence: true, allow_nil: true
这是灾难性的。如果用户试图通过提交带有新的
名称
但为空的
电子邮件
密码
字段的更新表单来仅更新其
名称
,则
名称
确实会更新,但
电子邮件
密码
属性也会更新为空值-
-因为验证不会运行

尝试2

allow\u nil:true
添加到验证:

validates :name,      length: {maximum: 50},           presence: true, on: :create
validates :email, uniqueness: {case_sensitive: false}, presence: true, on: :create
validates :password,  length: {minimum: 6},            presence: true, on: :create
validates :name,      length: {maximum: 50},           presence: true, allow_nil: true
validates :email, uniqueness: {case_sensitive: false}, presence: true, allow_nil: true
validates :password,  length: {minimum: 6},            presence: true, allow_nil: true
同样的灾难。您可以创建和更新具有空白属性的用户

尝试3次

仅在新记录或字段不为空时进行验证:

validates :email, uniqueness: {case_sensitive: false}, presence: true, if: :should_validate?

def should_validate?
  new_record? || email.present?
end
在Stackoverflow的其他地方,这已经被认为是正确的解决方案,但是如果我错了,请纠正我,这不是也是灾难性的吗?如果使用空白的
电子邮件
字段更新模型,
是否应验证?
将返回
,电子邮件验证将不会运行,数据库将使用空白的
电子邮件
更新

如果我错了,请纠正我,但是如果不验证也意味着不更新,则此“解决方案”将起作用,但这不是真的,是吗?如果不运行验证,该属性仍将保存到数据库右侧

尝试4次

在控制器中,如果属性为空,则从
params
中删除该属性:

user.rb

validates :name,      length: {maximum: 50},           presence: true
validates :email, uniqueness: {case_sensitive: false}, presence: true
validates :password,  length: {minimum: 6},            presence: true
validates :name,      length: {maximum: 50},           presence: true
validates :email, uniqueness: {case_sensitive: false}, presence: true
validates :password,  length: {minimum: 6},            presence: true
def update
  params[:user].delete(:name)     if params[:user][:name].blank?
  params[:user].delete(:email)    if params[:user][:email].blank?
  params[:user].delete(:password) if params[:user][:password].blank?

  if @user.update_attributes(update_user_params)
    flash[:success] = "Edit Successful."
    redirect_to @user
  else
    @title = "Edit user"
    render 'edit'
  end
end

def update_user_params
  params.require(:user).permit(:name, :email, :password)
end
validates :name,      length: {maximum: 50}
validates :email, uniqueness: {case_sensitive: false}
validates :password,  length: {minimum: 6}
def update
  params[:user].delete(:name)     if params[:user][:name].blank?
  params[:user].delete(:email)    if params[:user][:email].blank?
  params[:user].delete(:password) if params[:user][:password].blank?

  if @user.update_attributes(update_user_params)
    flash[:success] = "Edit Successful."
    redirect_to @user
  else
    @title = "Edit user"
    render 'edit'
  end
end
validates :name,      length: {maximum: 50},           presence: true, on: :create
validates :email, uniqueness: {case_sensitive: false}, presence: true, on: :create
validates :password,  length: {minimum: 6},            presence: true, on: :create

validates :name,      length: {maximum: 50},           on: :update
validates :email, uniqueness: {case_sensitive: false}, on: :update
validates :password,  length: {minimum: 6},            on: :update
def update
  params[:user].delete(:name)     if params[:user][:name].blank?
  params[:user].delete(:email)    if params[:user][:email].blank?
  params[:user].delete(:password) if params[:user][:password].blank?

  if @user.update_attributes(update_user_params)
    flash[:success] = "Edit Successful."
    redirect_to @user
  else
    @title = "Edit user"
    render 'edit'
  end
end
用户\u控制器.rb

validates :name,      length: {maximum: 50},           presence: true
validates :email, uniqueness: {case_sensitive: false}, presence: true
validates :password,  length: {minimum: 6},            presence: true
validates :name,      length: {maximum: 50},           presence: true
validates :email, uniqueness: {case_sensitive: false}, presence: true
validates :password,  length: {minimum: 6},            presence: true
def update
  params[:user].delete(:name)     if params[:user][:name].blank?
  params[:user].delete(:email)    if params[:user][:email].blank?
  params[:user].delete(:password) if params[:user][:password].blank?

  if @user.update_attributes(update_user_params)
    flash[:success] = "Edit Successful."
    redirect_to @user
  else
    @title = "Edit user"
    render 'edit'
  end
end

def update_user_params
  params.require(:user).permit(:name, :email, :password)
end
validates :name,      length: {maximum: 50}
validates :email, uniqueness: {case_sensitive: false}
validates :password,  length: {minimum: 6}
def update
  params[:user].delete(:name)     if params[:user][:name].blank?
  params[:user].delete(:email)    if params[:user][:email].blank?
  params[:user].delete(:password) if params[:user][:password].blank?

  if @user.update_attributes(update_user_params)
    flash[:success] = "Edit Successful."
    redirect_to @user
  else
    @title = "Edit user"
    render 'edit'
  end
end
validates :name,      length: {maximum: 50},           presence: true, on: :create
validates :email, uniqueness: {case_sensitive: false}, presence: true, on: :create
validates :password,  length: {minimum: 6},            presence: true, on: :create

validates :name,      length: {maximum: 50},           on: :update
validates :email, uniqueness: {case_sensitive: false}, on: :update
validates :password,  length: {minimum: 6},            on: :update
def update
  params[:user].delete(:name)     if params[:user][:name].blank?
  params[:user].delete(:email)    if params[:user][:email].blank?
  params[:user].delete(:password) if params[:user][:password].blank?

  if @user.update_attributes(update_user_params)
    flash[:success] = "Edit Successful."
    redirect_to @user
  else
    @title = "Edit user"
    render 'edit'
  end
end
这不起作用,因为验证中存在
presence:true
。如果
params
中不存在任何属性,则验证失败,记录不会更新

再说一次,这在Stackoverflow的其他地方被认为是正确的解决方案,所以我很确定我遗漏了什么,请告诉我在哪里

尝试5次

如果属性为空,则从
params
中删除该属性,并从验证中删除
presence:true

validates :name,      length: {maximum: 50},           presence: true, on: :create
validates :email, uniqueness: {case_sensitive: false}, presence: true, on: :create
validates :password,  length: {minimum: 6},            presence: true, on: :create
validates :name,      length: {maximum: 50},           presence: true, allow_nil: true
validates :email, uniqueness: {case_sensitive: false}, presence: true, allow_nil: true
validates :password,  length: {minimum: 6},            presence: true, allow_nil: true
user.rb

validates :name,      length: {maximum: 50},           presence: true
validates :email, uniqueness: {case_sensitive: false}, presence: true
validates :password,  length: {minimum: 6},            presence: true
validates :name,      length: {maximum: 50},           presence: true
validates :email, uniqueness: {case_sensitive: false}, presence: true
validates :password,  length: {minimum: 6},            presence: true
def update
  params[:user].delete(:name)     if params[:user][:name].blank?
  params[:user].delete(:email)    if params[:user][:email].blank?
  params[:user].delete(:password) if params[:user][:password].blank?

  if @user.update_attributes(update_user_params)
    flash[:success] = "Edit Successful."
    redirect_to @user
  else
    @title = "Edit user"
    render 'edit'
  end
end

def update_user_params
  params.require(:user).permit(:name, :email, :password)
end
validates :name,      length: {maximum: 50}
validates :email, uniqueness: {case_sensitive: false}
validates :password,  length: {minimum: 6}
def update
  params[:user].delete(:name)     if params[:user][:name].blank?
  params[:user].delete(:email)    if params[:user][:email].blank?
  params[:user].delete(:password) if params[:user][:password].blank?

  if @user.update_attributes(update_user_params)
    flash[:success] = "Edit Successful."
    redirect_to @user
  else
    @title = "Edit user"
    render 'edit'
  end
end
validates :name,      length: {maximum: 50},           presence: true, on: :create
validates :email, uniqueness: {case_sensitive: false}, presence: true, on: :create
validates :password,  length: {minimum: 6},            presence: true, on: :create

validates :name,      length: {maximum: 50},           on: :update
validates :email, uniqueness: {case_sensitive: false}, on: :update
validates :password,  length: {minimum: 6},            on: :update
def update
  params[:user].delete(:name)     if params[:user][:name].blank?
  params[:user].delete(:email)    if params[:user][:email].blank?
  params[:user].delete(:password) if params[:user][:password].blank?

  if @user.update_attributes(update_user_params)
    flash[:success] = "Edit Successful."
    redirect_to @user
  else
    @title = "Edit user"
    render 'edit'
  end
end
用户\u控制器.rb

validates :name,      length: {maximum: 50},           presence: true
validates :email, uniqueness: {case_sensitive: false}, presence: true
validates :password,  length: {minimum: 6},            presence: true
validates :name,      length: {maximum: 50},           presence: true
validates :email, uniqueness: {case_sensitive: false}, presence: true
validates :password,  length: {minimum: 6},            presence: true
def update
  params[:user].delete(:name)     if params[:user][:name].blank?
  params[:user].delete(:email)    if params[:user][:email].blank?
  params[:user].delete(:password) if params[:user][:password].blank?

  if @user.update_attributes(update_user_params)
    flash[:success] = "Edit Successful."
    redirect_to @user
  else
    @title = "Edit user"
    render 'edit'
  end
end

def update_user_params
  params.require(:user).permit(:name, :email, :password)
end
validates :name,      length: {maximum: 50}
validates :email, uniqueness: {case_sensitive: false}
validates :password,  length: {minimum: 6}
def update
  params[:user].delete(:name)     if params[:user][:name].blank?
  params[:user].delete(:email)    if params[:user][:email].blank?
  params[:user].delete(:password) if params[:user][:password].blank?

  if @user.update_attributes(update_user_params)
    flash[:success] = "Edit Successful."
    redirect_to @user
  else
    @title = "Edit user"
    render 'edit'
  end
end
validates :name,      length: {maximum: 50},           presence: true, on: :create
validates :email, uniqueness: {case_sensitive: false}, presence: true, on: :create
validates :password,  length: {minimum: 6},            presence: true, on: :create

validates :name,      length: {maximum: 50},           on: :update
validates :email, uniqueness: {case_sensitive: false}, on: :update
validates :password,  length: {minimum: 6},            on: :update
def update
  params[:user].delete(:name)     if params[:user][:name].blank?
  params[:user].delete(:email)    if params[:user][:email].blank?
  params[:user].delete(:password) if params[:user][:password].blank?

  if @user.update_attributes(update_user_params)
    flash[:success] = "Edit Successful."
    redirect_to @user
  else
    @title = "Edit user"
    render 'edit'
  end
end
这不管用。我们已经达到了要求2,但摧毁了要求1。使用此“解决方案”,您确实可以更新记录的各个属性,但也可以创建带有空白属性的新记录

尝试6次

我能看到的唯一可能的解决方案是对
on::create
on::update
进行不同的验证。如果要创建记录,则坚持使用
presence:true
,如果要更新记录,则删除
presence:true
。还需要在控制器中包含空白属性移除:

user.rb

validates :name,      length: {maximum: 50},           presence: true
validates :email, uniqueness: {case_sensitive: false}, presence: true
validates :password,  length: {minimum: 6},            presence: true
validates :name,      length: {maximum: 50},           presence: true
validates :email, uniqueness: {case_sensitive: false}, presence: true
validates :password,  length: {minimum: 6},            presence: true
def update
  params[:user].delete(:name)     if params[:user][:name].blank?
  params[:user].delete(:email)    if params[:user][:email].blank?
  params[:user].delete(:password) if params[:user][:password].blank?

  if @user.update_attributes(update_user_params)
    flash[:success] = "Edit Successful."
    redirect_to @user
  else
    @title = "Edit user"
    render 'edit'
  end
end

def update_user_params
  params.require(:user).permit(:name, :email, :password)
end
validates :name,      length: {maximum: 50}
validates :email, uniqueness: {case_sensitive: false}
validates :password,  length: {minimum: 6}
def update
  params[:user].delete(:name)     if params[:user][:name].blank?
  params[:user].delete(:email)    if params[:user][:email].blank?
  params[:user].delete(:password) if params[:user][:password].blank?

  if @user.update_attributes(update_user_params)
    flash[:success] = "Edit Successful."
    redirect_to @user
  else
    @title = "Edit user"
    render 'edit'
  end
end
validates :name,      length: {maximum: 50},           presence: true, on: :create
validates :email, uniqueness: {case_sensitive: false}, presence: true, on: :create
validates :password,  length: {minimum: 6},            presence: true, on: :create

validates :name,      length: {maximum: 50},           on: :update
validates :email, uniqueness: {case_sensitive: false}, on: :update
validates :password,  length: {minimum: 6},            on: :update
def update
  params[:user].delete(:name)     if params[:user][:name].blank?
  params[:user].delete(:email)    if params[:user][:email].blank?
  params[:user].delete(:password) if params[:user][:password].blank?

  if @user.update_attributes(update_user_params)
    flash[:success] = "Edit Successful."
    redirect_to @user
  else
    @title = "Edit user"
    render 'edit'
  end
end
用户\u控制器.rb

validates :name,      length: {maximum: 50},           presence: true
validates :email, uniqueness: {case_sensitive: false}, presence: true
validates :password,  length: {minimum: 6},            presence: true
validates :name,      length: {maximum: 50},           presence: true
validates :email, uniqueness: {case_sensitive: false}, presence: true
validates :password,  length: {minimum: 6},            presence: true
def update
  params[:user].delete(:name)     if params[:user][:name].blank?
  params[:user].delete(:email)    if params[:user][:email].blank?
  params[:user].delete(:password) if params[:user][:password].blank?

  if @user.update_attributes(update_user_params)
    flash[:success] = "Edit Successful."
    redirect_to @user
  else
    @title = "Edit user"
    render 'edit'
  end
end

def update_user_params
  params.require(:user).permit(:name, :email, :password)
end
validates :name,      length: {maximum: 50}
validates :email, uniqueness: {case_sensitive: false}
validates :password,  length: {minimum: 6}
def update
  params[:user].delete(:name)     if params[:user][:name].blank?
  params[:user].delete(:email)    if params[:user][:email].blank?
  params[:user].delete(:password) if params[:user][:password].blank?

  if @user.update_attributes(update_user_params)
    flash[:success] = "Edit Successful."
    redirect_to @user
  else
    @title = "Edit user"
    render 'edit'
  end
end
validates :name,      length: {maximum: 50},           presence: true, on: :create
validates :email, uniqueness: {case_sensitive: false}, presence: true, on: :create
validates :password,  length: {minimum: 6},            presence: true, on: :create

validates :name,      length: {maximum: 50},           on: :update
validates :email, uniqueness: {case_sensitive: false}, on: :update
validates :password,  length: {minimum: 6},            on: :update
def update
  params[:user].delete(:name)     if params[:user][:name].blank?
  params[:user].delete(:email)    if params[:user][:email].blank?
  params[:user].delete(:password) if params[:user][:password].blank?

  if @user.update_attributes(update_user_params)
    flash[:success] = "Edit Successful."
    redirect_to @user
  else
    @title = "Edit user"
    render 'edit'
  end
end

这允许吗??这样行吗??我是否完全错过了此问题的正确解决方案?

是否要在更新时将名称、电子邮件保存为零?我认为没有必要单独更新姓名、电子邮件。你只需在你想要的字段中进行更改,比如姓名或电子邮件,而不必将其他字段变为空白

如果需要用户名、电子邮件单独更新,只需在用户模型下创建setter方法,如下所示:

def name=(val)
  val = name if val.blank?
  self.write_attribute(name: val)
end

def email=(val)
  val = email if val.blank?
  self.write_attribute(email: val)
end 
不需要为更新用户编写单独的验证

validates :name,      length: {maximum: 50},           presence: true
validates :email, uniqueness: {case_sensitive: false}, presence: true
validates :password,  length: {minimum: 6},            presence: true
更新记录时您不允许使用用户参数。如果您使用的是Rails4,您可能会遇到例外情况。在users\u controller中创建或更新这样的记录之前,请确保您允许这些参数:

def user_params
   params.require(:user).permit(:name, :email, :password)
end
因此,您的更新操作将是:

def update
  if @user.update_attributes(user_params)
    flash[:success] = "Edit Successful."
    redirect_to @user
  else
    @title = "Edit user"
    render 'edit'
  end
end

是否要在更新时将名称、电子邮件保存为零?我认为没有必要单独更新姓名、电子邮件。你只需在你想要的字段中进行更改,比如姓名或电子邮件,不要让其他字段变为空白。绝对不会。姓名和电子邮件永远不应该更新为零。刚刚发布的解决方案看看对不起,我的意思是在问题中有强参数-我已经更正了。你是说尝试4会起作用吗?据我所知,你的解决办法是尝试4。验证中的
presence:true
是否会阻止此操作?如果希望解决方案4工作,则需要为电子邮件添加setter方法、名称和密码以处理空白值。如果值不存在,那么它将只接受旧值。我已经更新了setter方法,只需将其复制到用户模型中,它就可以工作了。不要对验证部分进行任何更改