【问题标题】:admin namespace with nested resources not saving具有嵌套资源的管理命名空间未保存
【发布时间】:2023-03-11 12:30:01
【问题描述】:

我在管理命名空间中创建嵌套资源时遇到问题。我对命名空间有些陌生。我已经阅读了 Stack 上的几篇文章,但无济于事,也许我执行不正确。

我有一个管理模型(设计),并试图将地址嵌套到我创建的自定义用户显示页面,这就是问题所在。

尝试为管理员创建新地址时,我在提交表单时收到此错误:

ActionController::UrlGenerationError at /admin/admins/2CE0/addresses
No route matches {:action=>"show", :admin_id=>"2CE0", :controller=>"admin/admins/admin/addresses"} missing required keys: [:id]

更好的错误页面的屏幕截图:

我的路线.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 路线输出:

  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

管理员模型:

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

管理控制器: - 请注意,这仅控制自定义管理索引和显示页面

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

地址模型:

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

地址控制器:

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

最后是在尝试共同创建新管理员地址时的 Rails 服务器控制台输出:

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]:

提前谢谢大家,我在这里陷入困境,不知道我从兔子洞的哪里掉下来!请询问您是否需要更多信息,我已尽力提供!

EDIT #1 - 添加控制器树的照片

【问题讨论】:

    标签: ruby ruby-on-rails-4 nested-forms


    【解决方案1】:

    如果您不熟悉命名空间,我建议您创建一个新应用,然后使用脚手架生成器在管理员命名空间中创建一个地址。然后查看脚手架构建对象的方式,并将其与您所拥有的进行比较。

    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 将以 Rails 开发人员期望的方式构建文件,这应该会告诉你如何去做。

    【讨论】:

    • 试一试,让你知道谢谢你的提示!
    • 在脚手架生成器中使用 Admin::Address 时,是否还需要使用 admin:references 来创建索引/主键?
    • 在应用的根目录下运行命令rails g model。输出是模型生成器的文档。它和网络上的任何东西一样好。底部是索引选项。与模型生成器使用的选项相同,可用于脚手架生成器。
    • 我看到了它的用途,但是当我在生成器中创建脚手架时,它没有嵌套它们,我的地址路由应该看起来像 admin/admin/id/address/new.. 我可以不让发电机来做这件事,我会一直玩弄它。
    猜你喜欢
    • 2012-10-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-01-14
    • 2011-07-06
    • 2011-02-12
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多