我使用的方法是
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
因此,当用户提交表单时,用户将在字段password_digest下使用加密密码创建,并且工作正常。
我的实际问题是一个控制器,让客户端通过发送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
i get:
{"errors":{"password":["can't be blank","is too short (minimum is 6 characters)"],"password_confirmation":["is too short (minimum is 6 characters)"]}}
看起来这个问题与参数包装有关http://api.rubyonrails.org/classes/ActionController/ParamsWrapper.html
由于您的json参数不在根节点下(并且您可能在config/initializers/wrap_parameters.rb中打开了参数包装),因此字段将自动包装在与控制器(user
)同名的根节点中。因为password
是一个虚拟属性,attribute_names
不返回,所以没有包装:
在没有:include或:exclude选项集的ActiveRecord模型上,它只包装类方法返回的参数吗attribute_names .
我认为正确的解决方案是在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
}
};
我找到了一个解决方案,也许不是最实用的,但它的工作…
我已经将create方法更改为:
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创建一个用户对象的实例,而de JSON没有人能告诉我为什么这个修复它?