Search code examples
ruby-on-railsmodel-view-controllermodelhyperlink

Link_to path for an object in a different model


I'm creating a Rails app with two sets of nested models:

Goal -> Stage -> Template

Contact -> Tracker -> Email

On the show page for my Goal, I can list all the Trackers related to that Goal and display information such as the title but I can't work out how to link to the Tracker.

I've tried many variations of link_to but nothing seems to work so I'd really appreciate some help. Thanks so much!

The config Routes.rb:

Rails.application.routes.draw do
  get 'pages/inbox'
  get 'pages/trackers'
  devise_for :users

  resources :contacts do
    resources :trackers do
      resources :emails
    end
  end
  resources :goals do
      resources :stages do
        resources :templates
      end
  end
  # Define your application routes per the DSL in https://guides.rubyonrails.org/routing.html

  # Defines the root path route ("/")
 root "contacts#index"
end

My Goal Controller:

  def show
    @trackers = Tracker.all
    @tracker = Tracker.all
  end

My Goal Model:

class Goal < ApplicationRecord
  has_many :stages , dependent: :destroy
  has_many :trackers
end

My Tracker Model:

class Tracker < ApplicationRecord
  belongs_to :contact
  belongs_to :goal
  belongs_to :stage
  has_many :emails , dependent: :destroy
end

Here is the Show.html.erb page for Goal with the wrong code for linking to the Tracker:

    <% for tracker in @goal.trackers %>
      <hr></hr>
            <%= link_to goal_tracker_path(@goal, tracker) do %> #Doesn't work
            <p><%= tracker.title %> | <%= tracker.contact.first_name %></p>
        <% end %>
     <% end %>

Solution

  • The tracker resource is not nested to goal but to contacts. The path goal_tracker_path (eg: /goals/1/trackers/1) does not exist. Only contact_tracker_path exists. You can see this if you run rails routes.

    There are couple ways you can go about this.

    • Do away with the nesting. But this will not have a nested url structure. The path would be /trackers/id. The link to will look something like
    link_to 'Title', tracker
    
    • Nest tracker resource to goal as well. In this case, both goal_tracker_path and contact_tracker_path will be available though both will be using the same TrackersController. You could always write another controller and specify it in the routes if it's needed. The routes will look something like
    resources :contacts do
        resources :trackers do
          resources :emails
        end
      end
      resources :goals do
          resources :trackers
          resources :stages do
            resources :templates
          end
      end
    
    • Or you could just move the tracker resource to goals resource unless you would need contact_tracker_path as well.

    It's best to always take a look at rails routes to make sure that the path exists.