web-dev-qa-db-fra.com

ActiveRecord: mettre à jour un enregistrement s'il existe, sinon, créer?

Essayer d'implémenter un enregistrement de mise à jour create sinon existant dans Active Record.

Utilise actuellement:

@student = Student.where(:user_id => current_user.id).first

if @student
    Student.destroy_all(:user_id => current_user.id)
end

Student = Student.new(:user_id => current_user.id, :department => 1
)
Student.save!

Quelle serait la bonne façon de mettre à jour le dossier s'il existe ou le crée? 

28
Rubytastic

Vous recherchez peut-être first_or_create ou quelque chose de similaire: 

http://guides.rubyonrails.org/v3.2.17/active_record_querying.html#first_or_create

13
sevenseacat

Dans Rails 4

Student.
  find_or_initialize_by(:user_id => current_user.id).
  update_attributes!(:department => 1)
58
Zorayr
@student = Student.where(user_id: current_user.id).first
@student ||= Student.new(user_id: current_user.id)
@student.department_id = 1
@student.save

C'est plus joli si vous avez une association entre un utilisateur et un étudiant. Quelque chose dans le sens de

@student = current_user.student || current_user.build_student
@student.department_id = 1
@student.save

MODIFIER:

Vous pouvez également utiliser http://guides.rubyonrails.org/active_record_querying.html#first_or_create selon la réponse de sevenseacat, mais vous devez toujours faire face à différents scénarios, tels que la mise à jour du numéro de service d'un étudiant.

METTRE À JOUR:

Vous pouvez utiliser find_or_create_by

@student = Student.find_or_create_by(user_id: current_user.id) do |student|
  student.department_id = 1
end
4
jvnill

Malheureusement, je pense que le moyen le plus propre de le faire est:

Student.where(user_id: id).first_or_create(age: 16).update_attribute(:age, 16)
0
Blair Anderson