Reputation: 1359
In my code, admins can add users and assign them jobs. If the admin decides to delete a user, I want to check for any jobs that the user may be assigned to and update its assignment to the admin. Since the user deletion is taking place in my user_controller and calling Jobs, is this the best way? If not, could you please advise as to the most efficient way to do this is, especially if the user is assigned to 1-N jobs? Thanks in advance.
users_controller.rb
def destroy
if admin?
jobs = Job.where("user_id = ?", params[:id]) #find jobs where user is that being deleted
jobs.each do |job|
job.update_attribute(:user_id, current_user.id) #for each job set the user_id to the admin_id
end
end
redirect_to users_url
end
Upvotes: 0
Views: 106
Reputation: 3365
I would propose using the update_all
call on an ActiveRecord::Relation
In your case, a simple way to make it happen would be:
Job.where(user_id: params[:id]).update_all(user_id: current_user.id)
Note that in newer versions of Rails (at least in the as-yet-unreleased 4), this will be prevented as mass assignment is dangerous. Because of that, you will want to 'whitelist' the user_id
attribute.
Upvotes: 1
Reputation: 40277
You can use the #update_all method to only execute one SQL query:
Here we will update all jobs with user_id of @user.id, set user_id to current_user.id
def destroy
@user = User.find(params[:id])
if admin?
Job.update_all {user_id: current_user.id}, {user_id: @user.id}
end
@user.destroy
redirect_to users_url
end
Upvotes: 1
Reputation: 6318
I would first select the jobs for that user in an instance variable, then loop over them updating the relevant foreign key to the admins user_id. then destroy the original record.
Upvotes: 0