Good day StackOverflow,
I have created an admin namespace, and within the namespace I have a client resource and nested in that is a site resource like so:
# routes.rb
namespace :admin do
resouurces :clients do
resources :sites
end
end
I am running into the following error when attempting to go from the "site" show page to the site "edit" page:
ActionController::UrlGenerationError at /admin/clients/9A81622C/sites/88AA/edit
and then BetterErrors gives me this below the error message:
No route matches {:action=>"show", :client_id=>nil, :controller=>"admin/clients/sites", :id=>"88AA"} missing required keys: [:client_id]
the rake routes output for the admin_client_site is as follows:
admin_client_sites POST /admin/clients/:client_id/sites(.:format) admin/clients/sites#create
new_admin_client_site GET /admin/clients/:client_id/sites/new(.:format) admin/clients/sites#new
edit_admin_client_site GET /admin/clients/:client_id/sites/:id/edit(.:format) admin/clients/sites#edit
admin_client_site GET /admin/clients/:client_id/sites/:id(.:format) admin/clients/sites#show
PATCH /admin/clients/:client_id/sites/:id(.:format) admin/clients/sites#update
PUT /admin/clients/:client_id/sites/:id(.:format) admin/clients/sites#update
DELETE /admin/clients/:client_id/sites/:id(.:format) admin/clients/sites#destroy
the edit link on the "show page" is currently as follows, and this is where the problem lies(or so I believe):
<%= link_to "Edit", edit_admin_client_site_path(@client, @site) %>
the form_for for client, sites is:
<%= form_for [:admin, @client, @site], :url => admin_client_sites_url do |f| %>
I Have spent the last day looking at various stack answers and still can not sort this out, any help here is greatly appreciated, thanks in advance and please let me know if you need any more documentation!
EDIT # 1 - Adds Client and Site Models
Client.rb
class Client < ActiveRecord::Base
before_create :generate_client_ident
# Model Relations
has_many :sites, dependent: :destroy
# Model Validations
validates_uniqueness_of :client_ident
# Unique Admin Identifier
def generate_client_ident
begin
self.client_ident = SecureRandom.hex(4).upcase
other_client = Client.find_by(client_ident: self.client_ident)
end while other_client
end
# Vanity URL
def to_param
client_ident
end
end
Site.rb
class Site < ActiveRecord::Base
before_create :generate_site_ident
# Model Relations
belongs_to :client
# Model Validations
validates_uniqueness_of :site_ident
# Unique Admin Identifier
def generate_site_ident
begin
self.site_ident = SecureRandom.hex(2).upcase
other_site = Site.find_by(site_ident: self.site_ident)
end while other_site
end
# Vanity URL
def to_param
site_ident
end
end
EDIT #2 - Adds Controllers
class Admin::Clients::SitesController < ApplicationController
before_action :authenticate_admin_admin!
before_action :set_site, only: [:show, :edit, :update, :destroy]
# GET /sites
# GET /sites.json
def index
@sites = Site.all
end
# GET /sites/1
# GET /sites/1.json
def show
@client = Client.find_by_client_ident(params[:id])
end
# GET /sites/new
def new
@client = Client.find_by_client_ident(params[:id])
@site = Site.new
end
# GET /sites/1/edit
def edit
@client = Client.find_by_client_ident(params[:id])
end
# POST /sites
# POST /sites.json
def create
@client = Client.find_by_client_ident(params[:id])
@site = Site.new(site_params)
@site.client = @client
respond_to do |format|
if @site.save
format.html { redirect_to admin_clients_url, notice: 'Site was successfully created.' }
format.json { render :show, status: :created, location: [:admin, @client] }
else
format.html { render :new }
format.json { render json: @site.errors, status: :unprocessable_entity }
end
end
end
# PATCH/PUT /sites/1
# PATCH/PUT /sites/1.json
def update
respond_to do |format|
if @site.update(site_params)
format.html { redirect_to [:admin, @client], notice: 'Site was successfully updated.' }
format.json { render :show, status: :ok, location: [:admin, @client] }
else
format.html { render :edit }
format.json { render json: @site.errors, status: :unprocessable_entity }
end
end
end
# DELETE /sites/1
# DELETE /sites/1.json
def destroy
@site.destroy
respond_to do |format|
format.html { redirect_to sites_url, notice: 'Site was successfully destroyed.' }
format.json { head :no_content }
end
end
private
# Use callbacks to share common setup or constraints between actions.
def set_site
@site = Site.find_by_site_ident(params[:id])
end
# Never trust parameters from the scary internet, only allow the white list through.
def site_params
params.require(:site).permit(:client_id, :site_ident)
end
end
class Admin::ClientsController < ApplicationController
before_action :authenticate_admin_admin!
before_action :set_client, only: [:show, :edit, :update, :destroy]
# GET /clients
# GET /clients.json
def index
@clients = Client.all
end
# GET /clients/1
# GET /clients/1.json
def show
@client = Client.find_by_client_ident(params[:id])
@site = @client.sites
end
# GET /clients/new
def new
@client = Client.new
end
# GET /clients/1/edit
def edit
end
# POST /clients
# POST /clients.json
def create
@client = Client.new(client_params)
respond_to do |format|
if @client.save
format.html { redirect_to [:admin, @client], notice: 'Client was successfully created.' }
format.json { render :show, status: :created, location: @client }
else
format.html { render :new }
format.json { render json: @client.errors, status: :unprocessable_entity }
end
end
end
# PATCH/PUT /clients/1
# PATCH/PUT /clients/1.json
def update
respond_to do |format|
if @client.update(client_params)
format.html { redirect_to [:admin, @client], notice: 'Client was successfully updated.' }
format.json { render :show, status: :ok, location: @client }
else
format.html { render :edit }
format.json { render json: @client.errors, status: :unprocessable_entity }
end
end
end
# DELETE /clients/1
# DELETE /clients/1.json
def destroy
@client.destroy
respond_to do |format|
format.html { redirect_to [:admin, @client], notice: 'Client was successfully destroyed.' }
format.json { head :no_content }
end
end
private
# Use callbacks to share common setup or constraints between actions.
def set_client
@client = Client.find_by_client_ident(params[:id])
end
# Never trust parameters from the scary internet, only allow the white list through.
def client_params
params.fetch(:client, {}).permit(:client_ident, :client_name, :street_number, :street_name, :unit_apt, :grid, :city,
:province, :postal_code, :office_tel, :office_ext, :cell_tel, :fax, :contact_email, :same_as_above,
:bill_to_client_name, :bill_to_street_number, :bill_to_street_name, :bill_to_grid, :bill_to_city,
:bill_to_province, :bill_to_postal_code)
end
end
EDIT #3 Adds ScreenShot Of Error
EDIT #4 - Adds Rails Server Log when clicking the Edit link on the "Site Show Page"
Started GET "/admin/clients/9A81622C/sites/88AA" for ::1 at 2016-05-25 14:10:51 -0600
Processing by Admin::Clients::SitesController#show as HTML
Parameters: {"client_id"=>"9A81622C", "id"=>"88AA"}
Admin Load (0.4ms) SELECT "admins".* FROM "admins" WHERE "admins"."id" = $1 ORDER BY "admins"."id" ASC LIMIT 1 [["id", 1]]
Site Load (0.2ms) SELECT "sites".* FROM "sites" WHERE "sites"."site_ident" = $1 LIMIT 1 [["site_ident", "88AA"]]
Client Load (0.2ms) SELECT "clients".* FROM "clients" WHERE "clients"."id" = $1 LIMIT 1 [["id", 9]]
Rendered admin/clients/sites/show.html.erb within layouts/application (3.4ms)
Completed 500 Internal Server Error in 12ms (ActiveRecord: 0.8ms)