Tell me more ×
Stack Overflow is a question and answer site for professional and enthusiast programmers. It's 100% free, no registration required.

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!

share|improve this question

2 Answers

up vote 2 down vote accepted

You can simply do

if @activity.location.itinerary.user_id == current_user.id
share|improve this answer
 
That solved it! Thanks, Ismael. Can you tell me the name for this approach of stringing together the different models? I'm a noob, but I'd like to learn more (and will google to find some good resources based on your response.) –  KDP Mar 1 at 18:20
 
You can do this tanks to the relations you set up with belongs_to and has_many which set those methods to you. You can find information about it ate the guides –  Ismael Abreu Mar 1 at 22:53

You really only need to ask the activity for its location, then ask the location for its itinerary, than ask it for its user. It's a bit of a violation of the Law of Demeter, but it will work.

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

That should work.

share|improve this answer
 
Austin, I really appreciate your response. I went with the other answer just because it was a simpler approach, but thank you for your time. –  KDP Mar 1 at 18:21

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.