Kombo
Kombo

Reputation: 2381

Restricting access by User in a related model's controller

I have a controller where I'm doing some kind of funky selection. I have an Invitation table that belongs_to a User, and has_one User.

When destroying an invitation, I want the "has_one User" to be be doing the destroying, is in my controller I'm first getting an array of invitations the User has been invited on with:

def destroy
    @invitations = Invitation.find_by_recipient_email(current_user.email)

From this @invitations array, I want to do a find using the :id parameter. Is there a way to do something like this:

@invitations = Invitation.find_by_recipient_email(current_user.email)
    @invitation = @invitations.find(params[:id])

That way I can limit the invitations the user can access only to the ones they've been invited on (with the current_user method) and then select the specific invitation. I currently can't do this as .find does not work on an array.

Thanks for the help/pointers.

edit: sorry I made the post kind of confusing, here's some more info:

Here's my entire destroy method right now, I only want to delete one record:

def destroy
    @invitations = Invitation.find_by_recipient_email(current_user.email)
    @invitation = @invitations.find(params[:id])  

    if @invitation.destroy
      redirect_to invitations_path, :notice => "Declined invitation"
    else
      redirect_to :back
    end
  end

My Invitation object looks like:

Invitation(id: integer, list_id: integer, sender_id: integer, recipient_email: string, created_at: datetime, updated_at: datetime) 

Where send_id and recipient_email are two different users.

My invitation.rb:

belongs_to :sender, :class_name => 'User'
  has_one :recipient, :class_name => 'User'

Maybe the issue is I would be calling something like current_users.invitations.find(params[:id]) and redo my invitation model?

Upvotes: 1

Views: 188

Answers (2)

klochner
klochner

Reputation: 8125

You can just do this:

invitatation_scope = Invitation.where(["recipient_email = ?",current_user.email])
@invitation =  invitation_scope.find(params[:id])

But you should use a before_filter:

before_filter :load_user_invitation, :only=>[:edit,:update,:destroy]

def load_user_invitation
  @invitation = Invitation.where(["recipient_email = ?",current_user.email]).find(params[:id])
end

Upvotes: 2

Jamison Dance
Jamison Dance

Reputation: 20184

find is an ActiveRecord method. You can use the Ruby enumerable method select to return an array of matching elements, and then get your invitation out of the array.

inv = @invitations.select { |i| i.id == params[:id] }
@inviation = inv.empty? ? nil : inv[0]

Upvotes: 2

Related Questions