Search code examples
ruby-on-railsrubymodel-view-controllerruby-on-rails-2

Restrict access to "destroy" feature in Ruby on Rails app


Thanks in advance for your help! I have a site built in Ruby on Rails (2.3.15, 1.8.7) that lets people create itineraries to different locations and with different activities at each location. The site has a way of ensuring that the current user can only delete the itineraries associated with his account. The code in itineraries_controller.rb to do this looks something like this:

def destroy
  @itinerary = Itinerary.find(params[:id])
  if @itinerary.user_id == current_user.id

    @itinerary.destroy

    respond_to do |format|
      format.html { redirect_to('/home') }
      format.xml  { head :ok }
    end
  else
    redirect_to '/'
  end
end

This system works well. I want to do the same thing for the activities, however. In the activities_controller, I want to ensure that the current user can only delete the activities associated with his account.

Currently, here are my four models (with unnecessary stuff stripped out):

User.rb

class User < ActiveRecord::Base
  has_many :itineraries
end

Itinerary.rb

class Itinerary < ActiveRecord::Base
  has_many :locations
  belongs_to :user
end

Location.rb

class Location < ActiveRecord::Base
  belongs_to :itinerary
  has_many :activities
end

Activity.rb

class Activity < ActiveRecord::Base
  belongs_to :location
end

Here is where I'm starting with activities_controller.rb. FYI, my current_user.id is created by an authenticated_system.rb, so don't worry about that part.

def destroy
  @activity = Activity.find(params[:id])
  if @itinerary.user_id == current_user.id

    @activity.destroy

    respond_to do |format|
      format.html { redirect_to("/") }
      format.xml  { head :ok }
    end
  else
    redirect_to '/'
  end
end

I tried to connect the models using a has_many :through approach, but I didn't know how to do it for more than three models, and I wasn't sure that was the right approach anyway. Thanks again for any help you can provide!


Solution

  • You can simply do

    if @activity.location.itinerary.user_id == current_user.id