Ruby on rails 仅更新强参数

Ruby on rails 仅更新强参数,ruby-on-rails,validation,strong-parameters,Ruby On Rails,Validation,Strong Parameters,首先,我相信一定有一些人,他们之前已经问过这个问题,但我不知道如何用谷歌搜索这个问题。所以,如果是重复的,我很抱歉 我在一个社交媒体网站上工作。我有一个用户模型,我用它向站点注册用户。它在注册时验证用户名、电子邮件和密码 我使用相同的模型让用户编辑他们的信息,比如用户名 这是我的更新控制器中的内容: def update # Find an existing object using form parameters @profile = User.find_by_id(cur

首先,我相信一定有一些人,他们之前已经问过这个问题,但我不知道如何用谷歌搜索这个问题。所以,如果是重复的,我很抱歉

我在一个社交媒体网站上工作。我有一个用户模型,我用它向站点注册用户。它在注册时验证用户名、电子邮件和密码

我使用相同的模型让用户编辑他们的信息,比如用户名

这是我的更新控制器中的内容:

  def update
    # Find an existing object using form parameters
    @profile = User.find_by_id(current_user.id)
    # Update the object
    if @profile.update_attributes!(settings_profile_params)
      # If save succeeds, redirect to itself
      redirect_to request.referrer
    else
      # If save fails, redisplay the form so user can fix the problems
      render('edit')
    end
  end

  private # user_params is not an action, that is why it is private.
  def settings_profile_params
    params.require(:user).permit(:first_name, :last_name, :username, :school, :program, :website, :information)
  end
问题是,我只想更新我在那里定义的强参数。但是由于密码验证,我得到了一个异常。我不知道为什么我会得到这个例外。如何设置系统以仅更新强参数中的值


谢谢。

通过调用
update\u attributes
可以隐式调用与其他更新和保存相同的验证范围。您需要更新所针对的特定参数(例如,省略
:password

在这里,我们可以将该允许键列表存储在可重用的变量中。然后,我们在每个键上调用
update\u属性
——在reduce中执行此操作,该reduce将为要编辑或显示的开关提供相同的
true
/
false

  def update
    # Find an existing object using form parameters
    @profile = User.find_by_id(current_user.id)
    # Update the object
    if PERMITTED_KEYS.reduce(true) {|bool, key| bool &&= @profile.update_attribute(key, @profile.send(key)) }
      # If save succeeds, redirect to itself
      redirect_to request.referrer
    else
      # If save fails, redisplay the form so user can fix the problems
      render('edit')
    end
  end

  private 

  PERMITTED_KEYS = [:first_name, :last_name, :username, :school, :program, :website, :information]

  # user_params is not an action, that is why it is private.
  def settings_profile_params
    params.require(:user).permit(PERMITTED_KEYS)
  end
由于以前没有使用过
strong_参数
gem,我认为这对于gem的使用更为惯用:

  def update
    # Find an existing object using form parameters
    @profile = User.find_by_id(current_user.id)
    # Update the object
    if settings_profile_params.keys.reduce(true) {|bool, key| bool &&= @profile.update_attribute(key, @profile.send(key)) }
      # If save succeeds, redirect to itself
      redirect_to request.referrer
    else
      # If save fails, redisplay the form so user can fix the problems
      render('edit')
    end
  end

  private 

  # user_params is not an action, that is why it is private.
  def settings_profile_params
    params.require(:user).permit(
      :first_name, :last_name, :username, 
      :school, :program, 
      :website, :information
    )
  end


尽管如此,我仍然认为这是一个重复的问题,因为它涉及如何在没有所有已定义验证的情况下更新模型数据。如果认为
update\u attributes
循环是保证不重复的足够独特的解决方案,我已经回答了这个问题

您可以通过更改密码验证来实现这一点。您需要添加密码验证的条件

# Password
  validates :password,
            :presence => {:message => 'Password cannot be blank'},
            :length => {:within => 8..99, :message => 'Password length should be within 8 and 99 characters'}
            :if => Proc.new { new_record? || !password.nil? }

好了,现在我发现问题了。首先,@Muntasim找到了解决这个问题的方法。但我实际上不需要使用这个解决方案,因为有另一种简单的方法来解决这个问题

在这种情况下,当我允许用户更新他们的配置文件时,rails不应该验证我的密码或用户模型中的任何其他列,如果我不要求的话。但为什么会这样呢?因为我在用户模型中有validates:password。相反,它必须是validates:digest_password。因为我正在使用bcrypt


我不知道为什么:尽管我使用了bcrypt,但注册时密码工作正常。

我认为您有一些Beforu filter操作,试图验证密码。您可以共享完整的控制器代码吗?还请共享
用户
模型可能与我添加的完整用户模型重复。您的代码出错。未定义的方法“更新属性!”对不起,
是错误的这工作非常好,它是干净的,但我从来没有见过像这样的“如果”。它能做什么?还有,为什么要删除lambda并使用Proc.new?我不记得这个语法。同意。另外,我还有一个问题。正如我所说,当我尝试更新记录时,会出现密码验证错误。但是,为什么我没有收到电子邮件验证错误?关于lambda或Proc:@Muntasim感谢您的帮助,您的回答解决了问题,但我实际上犯了一个愚蠢的错误,这就是为什么它不起作用。你可能想检查我分享的答案。你的用户模型没有显示bcrypt的用法,顺便说一句?没有,它有。这里:have\u secure\u password validations:false,好的,但是如果你想使用
validates:digest\u password。
你仍然需要这个条件,对吗?不,你不需要这个条件。问题是,正如你们所知,我们把所有的验证逻辑都放到了模型中。当你需要编辑一个值时,你必须使用强大的参数来分配质量。而且,在这个强参数中,无论您定义什么,模型都将自动验证它。所以,在我的例子中,用户的名字,因此我的模型检查它。但问题是密码。我并没有把密码放在强参数中,但模型仍然在验证它,这根本并没有意义。所以,问题是模型中的列名不对。@Muntasim好吧,我现在要发疯了。在我使用digest_密码后,一切都正常。但现在,30分钟后,它开始验证密码摘要。我想我需要你的条件。我不知道。。我只是很生气。