admin namespace with nested resources not saving

2019-09-13 23:27发布

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: Error Message Screenshot

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 enter image description here

1条回答
放我归山
2楼-- · 2019-09-13 23:43

If you are new to name spacing, I'd recommend creating a new app, and then using a scaffold generator to create an address in an admin names space. Then look at the way the scaffold builds the objects, and compare that to what you have.

rails new name_space_play
cd name_space_play
rails g scaffold Admin::Address street_number street_name street_type grid city province postal_code current

Scaffold will build the files in the way the rails developers expect them to be built, and that should show you how to do it.

查看更多
登录 后发表回答