Shawn Wilson Shawn Wilson - 6 months ago 36
Ruby Question

Cannot redirect to nil! (Error) - Rails 4 Nested Form

I am following a tutorial on Udemy and adding an address to my Custom Devise Admin #Show Page.

after completing the nesting and controller modifications I am getting this error in the address controller create redirect.

No route matches {:action=>"show", :admin_id=>"B1CA", :controller=>"admin"} missing required keys: [:id]


My Admin Controller:

class AdminController < ApplicationController
before_action :authenticate_admin!

def show
@admin = Admin.find_by_admin_ident(params[:id])
@addresses = @admin.addresses
end

def index
@admins = Admin.all
end

end


My Address Controller: - Provided full controller incase I have erred somewhere else thats causing this.

class Admin::AddressesController < ApplicationController
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_by_id(params[:admin_ident])
@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_ident])
@address = Address.new(address_params)
@address.admin = @admin

respond_to do |format|
if @address.save
format.html { redirect_to admin_path, notice: 'Address was successfully created.' }
format.json { render :show, status: :created, location: @admin }
else
format.html { render :new }
format.json { render json: @admin.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(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, :address_ident, :number, :name, :st_type, :unit_apt, :grid, :city, :province, :postal_code)
end
end


I am using custom identifiers as opposed to the standard rails /1 ect.. for id's this is how they are implemented.

Admin: - Exact same implementation in Addresses

class Admin < ActiveRecord::Base
before_create :generate_admin_ident

# Model Relations
has_many :addresses, dependent: :destroy
# Model Validations
validates_uniqueness_of :admin_ident

# Unique Ident Generator
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


My form_for: Oddly enough this is not namespaced, but loads the form as follows -

<%= form_for [:admin, @admin, @address] do |f| %>
...
<% end %>


My routes File:

devise_for :admins, controllers: { sessions: 'admins/sessions', registrations: 'admins/registrations', passwords: 'admins/passwords', confirmations: 'admins/confirmations', unlocks: 'admins/unlocks'}

#Nests Addresses to Admin
resources :admins, only: [:index, :show], controller: 'admin' do
resources :addresses, except: [:index], controller: 'admin/addresses'
end


My Controller File Layout
Controller file layout

Error Screen Better Errors
enter image description here

Please let me know if you want anymore information, I will do my best to accommodate!

EDIT # 1: - Rails Server Output

Started POST "/admins/B1CA/addresses" for ::1 at 2016-05-26 22:47:52 -0600
Processing by Admin::AddressesController#create as HTML
Parameters: {"utf8"=>"✓", "authenticity_token"=>"D2Sq2Pbq2bLxpOxBveSFf/3ivRJcm5jbhw39mnB/C1UnDll8z3fdEJMaf9315fcIaI6o7foTrvWrH7pT2y2BtA==", "address"=>{"admin_id"=>"", "address_ident"=>"", "number"=>"1234", "name"=>"Something", "st_type"=>"St", "unit_apt"=>"101", "grid"=>"SE", "city"=>"Calgary", "province"=>"AB", "postal_code"=>"T2B 5V5"}, "commit"=>"Create Address", "admin_id"=>"B1CA"}
Admin Load (0.3ms) SELECT "admins".* FROM "admins" WHERE "admins"."id" IS NULL LIMIT 1
(0.1ms) BEGIN
Address Exists (0.2ms) SELECT 1 AS one FROM "addresses" WHERE "addresses"."address_ident" = '' LIMIT 1
Address Load (0.1ms) SELECT "addresses".* FROM "addresses" WHERE "addresses"."address_ident" = $1 LIMIT 1 [["address_ident", "9F608A04"]]
SQL (0.1ms) INSERT INTO "addresses" ("address_ident", "number", "name", "st_type", "unit_apt", "grid", "city", "province", "postal_code", "created_at", "updated_at") VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11) RETURNING "id" [["address_ident", "9F608A04"], ["number", "1234"], ["name", "Something"], ["st_type", "St"], ["unit_apt", "101"], ["grid", "SE"], ["city", "Calgary"], ["province", "AB"], ["postal_code", "T2B 5V5"], ["created_at", "2016-05-27 04:47:52.551915"], ["updated_at", "2016-05-27 04:47:52.551915"]]
(0.8ms) COMMIT
Redirected to
Completed 500 Internal Server Error in 7ms (ActiveRecord: 1.7ms)

ActionController::ActionControllerError - Cannot redirect to nil!:


Rake Routes Output for Admin_Addresses:

admin_addresses POST /admins/:admin_id/addresses(.:format) admin/addresses#create
new_admin_address GET /admins/:admin_id/addresses/new(.:format) admin/addresses#new
edit_admin_address GET /admins/:admin_id/addresses/:id/edit(.:format) admin/addresses#edit
admin_address GET /admins/:admin_id/addresses/:id(.:format) admin/addresses#show
PATCH /admins/:admin_id/addresses/:id(.:format) admin/addresses#update
PUT /admins/:admin_id/addresses/:id(.:format) admin/addresses#update
DELETE /admins/:admin_id/addresses/:id(.:format) admin/addresses#destroy


Edit: #2: Error When redirect to path is:**
admin_addresses_path(@admin)


ActionController::UrlGenerationError at /admins/B1CA/addresses
No route matches {:action=>"create", :admin_id=>nil, :controller=>"admin/addresses"} missing required keys: [:admin_id]


Edit: 3 - Error when form for is set to below

<%= form_for [@admin, @address] do |f| %>
...
<% end %>

NoMethodError at /admins/B1CA/addresses/new
undefined method `addresses_path' for #<#<Class:0x007fc532933768>:0x007fc534b799a8>
Did you mean? admin_addresses_path

Answer

I think you May get wrong params for finding your admin. Change

@admin = Admin.find_by_id(params[:admin_ident])
format.html { redirect_to admin_path, notice: 'Address was successfully created.' }

To:

# admin_id here, not admin_ident
@admin = Admin.find_by_id(params[:admin_id])
format.html { redirect_to @admin, notice: 'Address was successfully created.' }

Or if you want to redirect to admin addresses:

# need to remove " except: [:index]" in your address routes
# routes
resources :addresses, controller: 'admin/addresses'"

# controller
format.html { redirect_to admin_addresses_path(@admin), notice: 'Address was successfully created.' }
Comments