#ruby-on-rails #ruby #devise #rubygems #devise-invitable
#ruby-on-rails #ruby #разработать #rubygems #devise-invitable
Вопрос:
Я хочу, чтобы приглашающий пользователь и приглашенный пользователь стали общими друзьями после принятия приглашения по электронной почте через devise_invitable (gem).
Итак, база данных должна быть такой:
id | user_id | friend_id | created_at | updated_at
---- --------- ----------- ---------------------------- ----------------------------
2 | 3 | 2 | 2020-10-13 02:42:03.33376 | 2020-10-13 02:42:03.33376
3 | 2 | 3 | 2020-10-13 15:57:48.359378 | 2020-10-13 15:57:48.359378
Вот что у меня есть в контроллере приглашений, который наследуется от источника. Код в середине, начинающийся с @inviting_user = User.find(current_user.invited_by_id)
того, что я вставил.
class Users::InvitationsController < Devise::InvitationsController
prepend_before_action :require_no_authentication, only: [:edit, :destroy]
def update
raw_invitation_token = update_resource_params[:invitation_token]
self.resource = accept_resource
invitation_accepted = resource.errors.empty?
yield resource if block_given?
if invitation_accepted
if resource.class.allow_insecure_sign_in_after_accept
flash_message = resource.active_for_authentication? ? :updated : :updated_not_active
set_flash_message :notice, flash_message if is_flashing_format?
resource.after_database_authentication
sign_in(resource_name, resource)
### from here is my code:
@inviting_user = User.find(current_user.invited_by_id)
@invited_user = User.find(current_user.id)
@friendship = @invited_user.friendships.build(:friend_id => params[:friend_id])
@inverse_friendship = @inviting_user.friendships.build(:friend_id => params[:friend_id])
if @friendship.save and @inverse_friendship.save
# flash[:notice] = "Added friend."
# redirect_back fallback_location: new_user_invitation_path
else
# flash[:error] = "Unable to add friend."
# redirect_back fallback_location: new_user_invitation_path
end
### my code end
respond_with resource, location: after_accept_path_for(resource)
else
set_flash_message :notice, :updated_not_active if is_flashing_format?
respond_with resource, location: new_session_path(resource_name)
end
else
resource.invitation_token = raw_invitation_token
respond_with_navigational(resource) { render :edit }
end
end
end
Проблема в том, что дружеские отношения не создаются. Я был бы признателен за любой совет.
Контроллер исходного кода: https://github.com/scambra/devise_invitable/blob/master/app/controllers/devise/invitations_controller.rb
Я начинаю думать, что проблема в этих двух строках, потому что @inviting_user и @invited_user, похоже, установлены. Видите ли вы какие-либо проблемы здесь, в контексте devise_invitable?
@friendship = @invited_user.friendships.build(:friend_id => params[:friend_id])
@inverse_friendship = @inviting_user.friendships.build(:friend_id => params[:friend_id])
Когда я переключаю @friendship.save на @friendship.create! Я получаю «вы имели в виду create_user?»
Ответ №1:
Вам действительно не нужна даже часть этого кода. Почти все контроллеры Devise уступают, поэтому вы можете просто подключиться к суперметоду, передав блок:
class Users::InvitationsController < Devise::InvitationsController
def update
super do |user|
Friendship.transaction do
begin
user.friendships.create!(friend_id: user.invited_by_id)
User.find(user.invited_by_id)
.friendships.create!(friend_id: user.id)
rescue ActiveRecord::RecordInvalid
flash[:error] = "Unable to add friend."
redirect_back fallback_location: new_user_invitation_path
raise ActiveRecord::Rollback
end
end
end
end
end
Комментарии:
1. Ты потрясающий! Спасибо!