【问题标题】:has_secure_password doesnt work on JSON but it does when form forhas_secure_password 在 JSON 上不起作用,但在 form 时起作用
【发布时间】:2014-05-09 16:24:33
【问题描述】:

我用的方法

has_secure_password 

在我理解的用户模型上创建了两个虚拟字段:

Password 
Password_confirmation

并验证它们的存在,所以在我身边我正在做这些其他验证:

validates :password  , length: {minimum: 6} 
validates :password_confirmation  , length: {minimum: 6}

在我看来,我有这种形式:

<%= form_for :user, url:{controller: 'users', action: 'create'}, html:{class:"form-horizontal"}  do |f| %>

        <div class="form-group">
          <%= f.label(:name, "Nombre", class:"control-label col-sm-1") %>
          <div class="col-sm-3">
          <%= f.text_field(:name, class:"form-control") %>
          </div>
        </div>

        <div class="form-group ">
              <%= f.label(:last_name, "Apellido", class:"control-label col-sm-1") %>
              <div class="col-sm-3">
                    <%= f.text_field(:last_name,  class:"form-control ") %>
              </div>
        </div>

        <div class="form-group ">
              <%= f.label(:cellphone, "Celular", class:"control-label col-sm-1") %>
              <div class="col-sm-3">
              <%= f.text_field(:cellphone, class:"form-control") %>
                </div>
        </div>

        <div class="form-group ">
              <%= f.label(:phone, "Telefono", class:"control-label col-sm-1") %>
              <div class="col-sm-3">
              <%= f.text_field(:phone, class:"form-control") %>
                </div>
        </div>

        <div class="form-group ">
              <%= f.label(:address, "Direccion", class:"control-label col-sm-1") %>
          <div class="col-sm-3">
              <%= f.text_field(:address, class:"form-control") %>
            </div>

        </div>

        <div class="form-group ">
              <%= f.label(:email, "Correo", class:"control-label col-sm-1") %>
            <div class="col-sm-3">
              <%= f.text_field(:email, class:"form-control") %>
            </div>
        </div>

        <div class="form-group ">
            <%= f.label(:password, "Contraseña", class:"control-label col-sm-1") %>
            <div class="col-sm-3">
                <%= f.password_field(:password, class:"form-control") %>
            </div>
        </div>

      <div class="form-group ">
        <%= f.label(:password_confirmation, "Confirmar Contraseña", class:"control-label col-sm-1") %>
        <div class="col-sm-3">
          <%= f.password_field(:password_confirmation, class:"form-control") %>
        </div>
      </div>

        <div class="form-group ">
            <%= f.label(:city_id, "Ciudad", class:"control-label col-sm-1") %>
            <div class="col-sm-3">
                 <%= f.select(:city_id, @cities.map {|c| [c.name, c.id]}) %>
            </div>

        </div>

        <div class="form-buttons">
            <%= submit_tag("Create Section") %>
        </div>

  <% end %>

并且控制器有这些动作:

def create

@user = User.new(user_params)
    if @user.save
      session[:user_id] = @user.id
      redirect_to controller: "users", action: "show"

    else
      @cities = City.all
      render 'new'
    end
  end

private

     def user_params
        params.require(:user).permit(:name, :last_name, :email, :address, :password,    :password_confirmation, :cellphone, :city_id, :phone)
      end

因此,当用户提交表单时,用户在密码摘要字段下使用加密密码创建了表单,并且工作正常。

我的实际问题是控制器让客户端通过发送 json 创建新用户,这是 api 控制器的方法:

respond_to :json

def create
    respond_with User.create(user_params)
end 

private

  def user_params
    params.require(:user).permit(:name, :last_name, :email, :address, :password, :password_confirmation, :cellphone, :city_id, :phone)
  end

当我发送这个 JSON 时:

var ad = {

            name:"juan",
            last_name:"paco",
            cellphone:"1234567890",
            phone:"1234567890",
            address:"porche",
            password:"porche",
            password_confirmation:"porche",
            email:"kkk@hj.com",
            city_id: 1,

        };

到

localhost.com:3000/api/v1/users/create

我明白了:

{"errors":{"password":["can't be blank","is too short (minimum is 6 characters)"],"password_confirmation":["is too short (minimum is 6 characters)"]}}

【问题讨论】:

  • password 和 password_confirmation 使用单引号而不是双引号。这很重要吗?
  • @GraemeMcLean 我不这么认为,只是我在尝试一些东西......但它不起作用。

标签: json ruby-on-rails-4 strong-parameters


【解决方案1】:

看起来这个问题与参数包装有关http://api.rubyonrails.org/classes/ActionController/ParamsWrapper.html

由于您的 json 参数不在根节点下(并且您可能在 config/initializers/wrap_parameters.rb 中打开了参数包装),因此这些字段将自动包装在与控制器同名的根中(@ 987654322@)。由于password 是一个虚拟属性并且不是由attribute_names 返回的,所以它没有被包装:

在没有设置 :include 或 :exclude 选项的 ActiveRecord 模型上,它 只会包装类方法返回的参数 属性名称。

我认为这里正确的解决方案是在wrap_parameters 的include 列表中指定password,方法是将其添加到UsersController 的顶部

wrap_parameters include: User.attribute_names + [:password]

或使用 user 根节点发出 JSON 请求

var ad = { 
          user: 
          {
            name:"juan",
            last_name:"paco",
            cellphone:"1234567890",
            phone:"1234567890",
            address:"porche",
            password:"porche",
            password_confirmation:"porche",
            email:"kkk@hj.com",
            city_id: 1
          }
        };

【讨论】:

  • 谢谢,但我没有得到带有用户根节点的 JSON 请求的第二个选项,我看到我正在发送相同的 json...
【解决方案2】:

我找到了一个解决方案,也许不是最实用的,但它确实有效......

我已将创建方法更改为:

 def create
    new_parms = user_params
    new_parms[:password] = params[:password]
    new_parms[:password_confirmation] = params[:password_confirmation]
    respond_with User.create(new_parms)
  end

因为我正在检查 Rails 服务器日志,我发现 html 请求的参数和 JSON 请求的参数存在一些差异。

当有人提交表单时,我会得到:

Started POST "/users/create" for 127.0.0.1 at 2014-05-09 16:56:07 -0400
Processing by UsersController#create as HTML
  Parameters: {"utf8"=>"✓", "authenticity_token"=>"5HZn9RRbdNAzSirAb9FauNYj/Jr/AAkKBecTvzrih/8=", "user"=>{"name"=>"", "last_name"=>"", "cellphone"=>"", "phone"=>"", "address"=>"", "email"=>"", "password"=>"[FILTERED]", "password_confirmation"=>"[FILTERED]", "city_id"=>"1"}, "commit"=>"Create Section"}

当我发送一个 JSON 请求时,我得到了这个:

Started GET "/api/v1/users/creando" for 127.0.0.1 at 2014-05-09 16:58:34 -0400
Processing by API::V1::UsersController#creando as JSON
  Parameters: {"name"=>"juan", "last_name"=>"paco", "cellphone"=>"1234567890", "phone"=>"1234567890", "address"=>"porche", "password"=>"[FILTERED]", "password_confirmation"=>"[FILTERED]", "email"=>"kkk@hj.com", "city_id"=>1, "commit"=>"Create Section", "authenticity_token"=>"5HZn9RRbdNAzSirAb9FauNYj/Jr/AAkKBecTvzrih/8=", "user"=>{"name"=>"juan", "last_name"=>"paco", "cellphone"=>"1234567890", "phone"=>"1234567890", "address"=>"porche", "email"=>"kkk@hj.com", "city_id"=>1}}

我认为这是为 form_for 创建 User 对象的实例,而 de JSON 没有人能告诉我为什么要修复它?

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-05-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-05-17
    • 2014-03-17
    • 1970-01-01
    相关资源
    最近更新 更多