Tengo un modelo de usuario, con nombre de usuario, dirección de correo electrónico, contraseña, confirmación de contraseña, nombre, avatar (imagen), etc. Hay validaciones en los primeros 5, básicamente indicando que los 5 deben existir para crear un nuevo modelo.Rieles: atributos de actualización que se enfrentan con las validaciones
Sin embargo, esto me causa problemas cuando se trata de actualizaciones.
Tengo una página de edición, donde el usuario solo puede editar su nombre y avatar. Actualmente, no tengo la intención de permitirles cambiar su nombre de usuario, y deseo hacer un cambio de correo electrónico y contraseña desde una página diferente.
Así el formulario de edición tiene el siguiente aspecto:
<% form_for @user, :html => { :multipart => true } do |u| %>
<p>
<label>Name:</label>
<%= u.text_field :name %>
</p>
<p>
<label>Avatar:</label>
<%= display_user_avatar %>
<%= u.file_field :avatar%>
</p>
<p>
<%= submit_tag %>
</p>
<% end %>
Si intento hacer un @user.update_attributes(params[:user])
, a continuación, ya que los únicos 2 params son name
y avatar
, la actualización falla, ya que cosas como contraseña, confirmación de la contraseña, correo electrónico, etc. son necesarios para validar la entrada, y simplemente no existen en esa forma.
Puedo solucionar esto haciendo @user.update_attribute(:name, params[:user][:name])
, pero luego me preocupa si evitar las validaciones es algo bueno o no. Especialmente en lo que respecta a algo así como actualizaciones de contraseña, donde I do necesita validar la nueva contraseña.
¿Hay otra manera?
Y si yo fuera hacer esto simplemente utilizando update_attribute para :name
y :avatar
, ¿cómo voy a ir haciendo sobre él?
¿Funcionaría?
params[:user].each do |attribute|
@user.update_attribute(attribute, params[:user][attribute])
end
¿Es esta una manera aceptable de hacer esto ...?
--edit como seguimiento -
Okie, me trató como usted sugiere y lo hizo
Así que está haciendo la versión !
, y la excepción atrapado & que aparece en el navegador es decir:
Validation failed: Password is too short (minimum is 5 characters)
la información en el registro del servidor es:
Processing UsersController#update (for 127.0.0.1 at 2010-07-18 11:56:59) [PUT]
Parameters: {"user"=>{"name"=>"testeeeeee"}, "commit"=>"Save changes", "action"=>"update", "_method"=>"put", "authenticity_token"=>"BMEGRW/pmIJVs1zlVH2TtZX2TQW8soeCXmMx4kquzMA=", "id"=>"tester", "controller"=>"users"}
Urm. Al ver esto, me acabo de dar cuenta de que está enviando "id"=>"tester"
. Ahora, tengo mis rutas configuradas para que muestren el nombre de inicio de sesión de los usuarios, en lugar del user_id ... ¿Podría ser ese el motivo? Está intentando encontrar una actualización para un usuario con user_id == tester
, pero dado que no existe, ¿intenta crear una en su lugar? ¿De verdad es algo que estoy haciendo mal debido a la ruta?
Hmmm ...rutas rastrillo me dice que la ruta es:
edit_user GET /users/:id/edit(.:format) {:action=>"edit", :controller=>"users"}
PUT /users/:id(.:format) {:action=>"update", :controller=>"users"}
Y He definido la ruta de esa manera en el archivo user.rb
:
def to_param
"#{login}"
end
pero definitivamente ha estado mostrando login
en lugar de id
todo este tiempo. Pero también estoy haciendo lo correcto al comienzo de la acción de actualización, un @user = User.find_by_login(params[:id])
, y luego actualizando ese @user
.
Estoy muy confundido. >. <
Segunda actualización:
Mi User.rb
cosas validación son los siguientes:
validates_length_of :login, :within => 3..20
validates_length_of :password, :within => 5..20
validates_presence_of :login, :email, :password, :password_confirmation, :salt, :name, :on => :create
validates_uniqueness_of :login, :case_sensitive => false
validates_confirmation_of :password
validates_format_of :email, :with => /^([^@\s]+)@((?:[-a-z0-9]+\.)+[a-z]{2,})$/i, :message => "format is invalid."
attr_accessor :password, :password_confirmation
Y la sección hashed_password está aquí:
def password=(pass)
@password = pass
self.salt = User.random_string(10) if !self.salt?
self.hashed_password = User.encrypt(@password, self.salt)
end
u.attributes
me da
>> u.attributes
=> {"salt"=>"NHpH5glxsU", "name"=>"test er", "avatar_updated_at"=>nil, "updated_at"=>Sat Jul 17 07:04:24 UTC 2010, "avatar_file_size"=>nil, "avatar_file_name"=>nil, "hashed_password"=>"84f8675c1ed43ef7f8645a375ea9f867c9a25c83", "id"=>1, "avatar_content_type"=>nil, "login"=>"tester", "email"=>"[email protected]", "created_at"=>Fri May 07 10:09:37 UTC 2010}
Urmmm ... Ok, así que es lo que ha dicho, sobre el atributo virtual password
estar realmente inexistente ... Entonces, ¿Cómo me manejo en que? Error, aquí pensé que estaba siendo inteligente manipulando mi propio código de autenticación ...
¿Qué tan fácil es cambiar a uno de esos complementos de autenticación? ¿Tendré que crear un nuevo modelo de usuario? ¿O debería el complemento poder trabajar con mi actual?
¡Gracias por toda la ayuda hasta ahora, por cierto! : D
PD: Sí, el '
Lo que describes no me suena del todo bien. Estoy bastante seguro de que si haces 'update_attributes' con un' Hash' que contiene solo un conjunto parcial de los atributos, entonces todos los otros atributos se quedan con sus valores anteriores significan que la validación no debe fallar. – mikej