Search code examples
ruby-on-railsvariablesparametersoperatorsdestroy

How do I use || operator so destroy ccurs in either of 2 instances?


I have 2 situations where I want a relationship to be destroyed. 1. when an active relationship is deleted 2. when a passive relationship is deleted.

At the moment each situation works on it's own. But when I try to set it up so either work at the same time I get an active record error. It's something to do with the destroy method not being able to find the relationship for the params[:id] in both occurrences. maybe it's how i'm using the || operator?

At the moment, if I try to delete a passive relationship it works. but then if i try to delete an active one I get the active record error shown below:

ActiveRecord::RecordNotFound in RelationshipsController#destroy
Couldn't find Relationship with 'id'=1 [WHERE "relationships"."followed_id" = ?]

If I change the code so def destroy has active before passive:

@relationship = current_user.active_relationships.find(params[:id]) || current_user.passive_relationships.find(params[:id]) 

then the active_relationship delete works, but the passive_relationship delete returns the active record issue. (this time with:

ActiveRecord::RecordNotFound in RelationshipsController#destroy
    Couldn't find Relationship with 'id'=1 [WHERE "relationships"."follower_id" = ?]

how do i let it know it's ok if

@relationship = current_user.active_relationships.find(params[:id]) || current_user.passive_relationships.find(params[:id]

only finds one of the relationships using the id provided?

relationships/edit: (VIEW)

<% if @active_relationship %>
    <% if @active_relationship.pending? %>
        <%= form_for @active_relationship, url: relationship_path(@active_relationship), method: :delete do |form| %>
        <%= submit_tag "Delete Request", class: 'btn btn-danger' %>
        <% end %>
    <% end %>
<% end %>

<% if @passive_relationship %>
    <% if @passive_relationship.pending? %>
        <%= form_for @passive_relationship, url: relationship_path(@passive_relationship), method: :delete do |form| %>
        <%= submit_tag "Decline Relationship", class: 'btn btn-danger' %>
        <% end %>
    <% end %>
<% end %>

relationship controller:

def destroy
    @relationship = current_user.passive_relationships.find(params[:id]) || current_user.active_relationships.find(params[:id])
    if @relationship.destroy
      flash[:success] = "Relationship destroyed"
    end
    redirect_to root_path
  end

Solution

  • Try this way.

    Create a method in your app/models/user.rb(User):

    def find_by_passive_or_active_relatioship(id)
      passive_relationships.where(id: id).first || active_relationships.where(id: id).first
    end
    

    then in your controller:

    def destroy
      @relationship = current_user.find_by_passive_or_active_relatioship(params[:id])
      if @relationship.try(:destroy)
        flash[:success] = "Relationship destroyed"
      else
        flash[:error] = 'Relationship can be destroyed at the moment. Try again.'
      end
      redirect_to root_path
    end
    

    You can use, find_by method instead of where(id: id), depending on your Rails version.

    find raises RecordNotFound exception if it doesn't find the resource, while where().first or find_by methods don't.