I am having an issue with creating nested resources in my admin namespace. I am somewhat new to namespaces. I have read several posts on Stack but to no avail, perhaps i am implementing this incorrectly.
I have an admin model (devise), and am trying to nest an address to the custom user show page I have created, this is where the problem is.
When trying to create a new address for an admin I get this error when I submit the form:
ActionController::UrlGenerationError at /admin/admins/2CE0/addresses
No route matches {:action=>"show", :admin_id=>"2CE0", :controller=>"admin/admins/admin/addresses"} missing required keys: [:id]
A Screen Shot of the Better Errors Page:
My Routes.rb
namespace :admin do
devise_for :admins, controllers: { sessions: 'admin/admins/sessions', passwords: 'admin/admins/passwords', registrations: 'admin/admins/registrations', confirmations: 'admin/admins/confirmations', unlocks: 'admin/admins/unlocks', shared: 'admin/admins/shared' }
resources :admins, controller: 'admins/admin', shallow: true do
resources :addresses, except: [:index], controller: 'admins/admin/addresses'
end
end
###Admin Authentication Scope###
devise_scope :admin do
authenticated do
root to: 'admin/admin_static#home', as: 'authenticated_admin'
end
end
Rake Routes Output:
admin_admin_addresses POST /admin/admins/:admin_id/addresses(.:format) admin/admins/admin/addresses#create
new_admin_admin_address GET /admin/admins/:admin_id/addresses/new(.:format) admin/admins/admin/addresses#new
edit_admin_address GET /admin/addresses/:id/edit(.:format) admin/admins/admin/addresses#edit
admin_address GET /admin/addresses/:id(.:format) admin/admins/admin/addresses#show
PATCH /admin/addresses/:id(.:format) admin/admins/admin/addresses#update
PUT /admin/addresses/:id(.:format) admin/admins/admin/addresses#update
DELETE /admin/addresses/:id(.:format) admin/admins/admin/addresses#destroy
The Admin Model:
class Admin < ActiveRecord::Base
before_create :generate_admin_ident
# Devise Modules
devise :database_authenticatable, :registerable,:recoverable, :rememberable,
:trackable, :validatable, :confirmable, :lockable, :timeoutable
# Model Relationships
has_many :addresses, dependent: :destroy
# Model Validations
validates_uniqueness_of :admin_ident
#Unique Identifier Generation
def generate_admin_ident
begin
self.admin_ident = SecureRandom.hex(2).upcase
other_admin = Admin.find_by(admin_ident: self.admin_ident)
end while other_admin
end
# Vanity URL
def to_param
admin_ident
end
end
The Admin Controller: - Note this only controls a custom admin index and show page
class Admin::Admins::AdminController < ApplicationController
before_action :authenticate_admin_admin!
def index
@admins = Admin.all
end
def show
@admin = Admin.find_by_admin_ident(params[:id])
@addresses = @admin.addresses
end
def new
end
def edit
end
def create
end
def update
end
def destroy
end
end
The Address Model:
class Address < ActiveRecord::Base
before_create :generate_address_ident
# Model Relationships
belongs_to :admin
# Model Validations
validates_uniqueness_of :address_ident
#Unique Identifier Generation
def generate_address_ident
begin
self.address_ident = SecureRandom.hex(4).upcase
other_address = Address.find_by(address_ident: self.address_ident)
end while other_address
end
# Vanity URL
def to_param
address_ident
end
end
The Address Controller:
class Admin::Admins::Admin::AddressesController < ApplicationController
before_action :authenticate_admin_admin!
before_action :set_address, only: [:show, :edit, :update, :destroy]
# GET /addresses
# GET /addresses.json
def index
@addresses = Address.all
end
# GET /addresses/1
# GET /addresses/1.json
def show
end
# GET /addresses/new
def new
@admin = Admin.find(params[:admin_id])
@address = Address.new
end
# GET /addresses/1/edit
def edit
end
# POST /addresses
# POST /addresses.json
def create
@admin = Admin.find_by_id(params[:admin_id])
@address = Address.new(address_params)
respond_to do |format|
if @address.save
format.html { redirect_to admin_admin_address_url[:admin, @admins, @address], notice: 'Address was successfully created.' }
format.json { render :show, status: :created, location: @address }
else
format.html { render :new }
format.json { render json: @address.errors, status: :unprocessable_entity }
end
end
end
# PATCH/PUT /addresses/1
# PATCH/PUT /addresses/1.json
def update
respond_to do |format|
if @address.update(address_params)
format.html { redirect_to @address, notice: 'Address was successfully updated.' }
format.json { render :show, status: :ok, location: @address }
else
format.html { render :edit }
format.json { render json: @address.errors, status: :unprocessable_entity }
end
end
end
# DELETE /addresses/1
# DELETE /addresses/1.json
def destroy
@address.destroy
respond_to do |format|
format.html { redirect_to addresses_url, notice: 'Address was successfully destroyed.' }
format.json { head :no_content }
end
end
private
# Use callbacks to share common setup or constraints between actions.
def set_address
@address = Address.find_by_address_ident(params[:id])
end
# Never trust parameters from the scary internet, only allow the white list through.
def address_params
params.require(:address).permit(:admin_id, :street_number, :street_name, :street_type, :grid, :city, :province, :postal_code, :current)
end
end
And Finally the Rails Server Console output when trying co create a new admin address:
Started POST "/admin/admins/2CE0/addresses" for ::1 at 2016-05-25 22:54:40 -0600
Processing by Admin::Admins::Admin::AddressesController#create as HTML
Parameters: {"utf8"=>"✓", "authenticity_token"=>"i+B7DS85BtWIA9xsAQnzPByayTZ9Z4fI4rTkEcBqfgkQw9CFTFUMaRhUDyQKYgzA9SPNYWJIkyU8lcnyODYKuw==", "address"=>{"admin_id"=>"", "street_number"=>"1234", "street_name"=>"something", "street_type"=>"AVE", "grid"=>"NW", "city"=>"YYC", "province"=>"AB", "postal_code"=>"123 456", "current"=>"0"}, "commit"=>"Create Address", "admin_id"=>"2CE0"}
Admin Load (0.2ms) SELECT "admins".* FROM "admins" WHERE "admins"."id" = $1 ORDER BY "admins"."id" ASC LIMIT 1 [["id", 1]]
Admin Load (0.4ms) SELECT "admins".* FROM "admins" WHERE "admins"."id" = $1 LIMIT 1 [["id", 2]]
(0.1ms) BEGIN
Address Exists (0.2ms) SELECT 1 AS one FROM "addresses" WHERE "addresses"."address_ident" IS NULL LIMIT 1
Address Load (0.1ms) SELECT "addresses".* FROM "addresses" WHERE "addresses"."address_ident" = $1 LIMIT 1 [["address_ident", "1F185CE6"]]
SQL (0.1ms) INSERT INTO "addresses" ("street_number", "street_name", "street_type", "grid", "city", "province", "postal_code", "current", "created_at", "updated_at", "address_ident") VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11) RETURNING "id" [["street_number", "1234"], ["street_name", "something"], ["street_type", "AVE"], ["grid", "NW"], ["city", "YYC"], ["province", "AB"], ["postal_code", "123 456"], ["current", "f"], ["created_at", "2016-05-26 04:54:40.377296"], ["updated_at", "2016-05-26 04:54:40.377296"], ["address_ident", "1F185CE6"]]
(5.9ms) COMMIT
Completed 500 Internal Server Error in 39ms (ActiveRecord: 9.5ms)
ActionController::UrlGenerationError - No route matches {:action=>"show", :admin_id=>"2CE0", :controller=>"admin/admins/admin/addresses"} missing required keys: [:id]:
Thank you all in advance, I am in a bind here and not sure where I fell down the Rabbit hole! Please ask if you need more information, I have tried to provide as much as possible!
EDIT # 1 - Adds Photo Of Controller Tree