I set up a controller alert to alert me when the index or show routes come back nil when trying to route to them i.e. I click on the link_to link for hero involved "Thor" and receive this error.
What I am trying to accomplish eventually is to try to nest these routes together so all heroes and eventually villains will be associated and nested within the report routes and users will eventually be able to enter a new hero if it's not there already. However, it doesn't seem to be assigning a hero_id or villain_id. However, it does assign the user_id of the user that submitted the report.
I suspect it has something to with my associations being off or not correctly synced up, but I could be wrong.
Hero Controller
def index
if params[:report_id]
@report = Report.find_by(id: params[:report_id])
if @report.nil?
redirect_to reports_path, alert: "Report not found"
else
@heros = @reports.heros
end
else
@heros = Hero.all
end
end
def show
if params[:report_id]
@report = Report.find_by(id: params[:report_id])
@hero = @report.heros.find_by(id: params[:id])
if @hero.nil?
flash[:notice] = "Hero not found"
redirect_to report_hero_path(@report)
end
else
@hero = Hero.find(params[:id])
end
end
def create
@hero = Hero.build(hero_params)
if @hero.save
flash[:notice] = "Hero was successfully created"
redirect_to @hero
else
render 'new'
end
end
def hero_params
params.require(:hero).permit(:hero_name)
end
Report Controller Params
def report_params
#byebug
params.require(:report).permit(:subject, :description, :hero_ids, :villain_ids)
end
Report Model
class Report < ApplicationRecord
validates :subject, presence: true, length: { minimum: 6, maximum: 100 }
validates :description, presence: true, length: { minimum: 10, maximum: 300 }
belongs_to :user
has_many :report_heros
has_many :heros, through: :report_heros
has_many :report_villains
has_many :villains, through: :report_villains
end
Hero Model
class Hero < ApplicationRecord
validates :hero_name, presence: true, length: { minimum: 3, maximum: 25 }
validates_uniqueness_of :hero_name
has_many :report_heros
has_many :reports, through: :report_heros, dependent: :destroy
end
Routes
Rails.application.routes.draw do
devise_for :users, controllers: { omniauth_callbacks: 'users/omniauth_callbacks' },
skip: [:mailer, :unlocks, :passwords, :confirmations]
resources :users, except: :new
resources :reports do
resources :heros, only: [:index, :new, :show]
end
resources :heros
resources :villains
get 'about', to: 'pages#about'
root 'pages#home'
end
Index for Reports
<div class="container">
<h1 class="row justify-content-center">Report Index</h1>
<table class="table table-bordered bg-light">
<thead bgcolor="#959595">
<tr>
<th scope="col">Subject</th>
<th scope="col">Description</th>
<th scope="col">Created By</th>
<th scope="col">Hero Involved</th>
<th scope="col">Villain Involved</th>
<th scope="col">Edit</th>
<th scope="col">Delete</th>
</tr>
</thead>
<tbody>
<% @reports.each do |report|%>
<tr>
<td><%= report.subject %></td>
<td><%= report.description %></td>
<td><%= link_to report.user.email, report_path(report) %></td>
<% report.heros.each do |hero|%>
<td><%= link_to hero.hero_name, report_heros_path(:hero_id, :report_id) %></td>
<% end %>
<% report.villains.each do |villain|%>
<td><%= villain.villain_name %></td>
<% end %>
<% if report.user == current_user %>
<td><%= link_to "Edit Report", edit_report_path(report) %></td>
<td><%= link_to "Delete Report", report_path(report), method: :delete, data: {confirm: "Are you sure?"} %></td>
<% end %>
</tr>
<% end %>
</tbody>
</table>
<%= link_to 'New Report', new_report_path, class: "btn btn-primary" %>
</div>