Использование devise_invitable, при принятии, сохранение взаимной дружбы

#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. Ты потрясающий! Спасибо!