I have a Rails 5 app where users can sign up as guest User
s to try out my service. Each User
(and guest user) can have many App
s. The relationship looks like this:
# User.rb
has_many :apps, dependent: :destroy
# App.rb
belongs_to :user
When a guest user decides to sign up to the service I want to:
The problem I'm having is that the app gets deleted even if I reassign the app.user
to my new current_user
(I use the Device gem), before deleting the old guest user.
In my class Users::RegistrationsController < Devise::RegistrationsController
I override the create
action like this (the relevant parts):
# POST /resource
def create
user_params = params[:user]
new_user_from_guest = guest_user
build_resource(sign_up_params)
resource.save
yield resource if block_given?
if resource.persisted?
if resource.active_for_authentication?
set_flash_message :notice, :signed_up if is_flashing_format?
sign_up(resource_name, resource)
# Reassigns the app
reasign_app_for_user(new_user_from_guest)
Mailer.deliver_welcome_message(current_user).deliver_later!
respond_with resource, location: after_sign_up_path_for(resource)
# delete the guest user (this also deletes the app)
delete_guest_user!
else
[...]
end
else
[...]
end
end
# ... my private methods for deleting the current user and reassigning the app's owner.
def reasign_app_for_user(user)
user.apps.each do |app|
app.user = current_user
app.save!
end
end
# ... this method deletes the app, even if it is called after the reassign method.
def delete_guest_user!
guest_user(with_retry = false).try(:destroy)
session[:guest_user_id] = nil
end
Any ideas on why this is happening or what I'm doing wrong?
Update
This is how my user_params
variable look like after submit:
<ActionController::Parameters {"name"=>"Test user", "email"=>"test@example.com", "password"=>"testing"} permitted: false>
And this is how sign_up_params
look:
{"email"=>"test@example.com", "password"=>"testing", "name"=>"Test"}
I would consider duplicating the apps before assigning them to the new user. This way, there's no confusion about if it's the same app or not.
guest.apps.each do |app|
current_user.apps << app.dup
end
Simply like this. The shovel operator ensures that the new, duplicated app is saved to the current_user
object.
Or even simpler and more compact:
current_user.apps = guest.apps.map(&:dup)
current_user.save